ActiveDirectory 모듈이 필요하다. 도메인 컨트롤러에는 기본으로 들어 있고, 관리 워크스테이션에서는 RSAT 를 설치한다.
Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0
Import-Module ActiveDirectory
Get-ADUser -Filter * | Select-Object Name, SamAccountName, Enabled
Get-ADUser 는 기본적으로 몇 개 속성만 가져온다. 다른 속성이 필요하면 -Properties 로 명시해야 한다. 지정하지 않은 속성은 값이 있어도 빈칸으로 나온다.
Get-ADUser -Filter * -Properties DisplayName, Mail, LastLogonDate, whenCreated |
Select-Object SamAccountName, DisplayName, Mail, LastLogonDate |
Sort-Object LastLogonDate
범위를 좁히려면 -SearchBase 로 OU 를 지정한다. 조직이 크면 전체 조회는 시간이 오래 걸리고 DC 부하도 크다.
Get-ADUser -Filter * -SearchBase 'OU=bigdata,DC=example,DC=com' -SearchScope Subtree
특정 그룹의 구성원은 Get-ADUser -Filter 로 MemberOf 를 비교하는 것보다 전용 명령이 정확하다. 중첩 그룹까지 풀어야 하면 -Recursive 를 준다.
Get-ADGroupMember -Identity 'DataPlatform-Users' -Recursive |
Get-ADUser -Properties Mail |
Select-Object SamAccountName, Name, Mail
CSV 로 넘길 때는 인코딩을 지정한다. 한글 표시 이름이 깨진다.
... | Export-Csv C:\temp\ad_users.csv -NoTypeInformation -Encoding UTF8
Search-ADAccount -AccountInactive -UsersOnly -TimeSpan 90.00:00:00 |
Select-Object SamAccountName, Name, LastLogonDate, DistinguishedName
Search-ADAccount 는 -AccountInactive 외에 -AccountDisabled, -AccountExpired, -PasswordExpired, -LockedOut 를 지원한다.
판정 기준이 LastLogonTimeStamp 라는 점을 알고 써야 한다. 이 속성은 도메인 컨트롤러 간에 복제되지만, 복제 부하를 줄이려고 기본 9~14일의 지연을 두고 갱신된다. 따라서 조회 결과의 마지막 로그온 시각은 최대 2주 정도 과거일 수 있다. 정확한 시각이 필요하면 모든 DC 의 lastLogon (복제되지 않는 속성) 을 각각 읽어 가장 최근 값을 골라야 한다.
$dcs = (Get-ADDomainController -Filter *).HostName
foreach ($dc in $dcs) {
Get-ADUser user01 -Server $dc -Properties lastLogon |
Select-Object @{n='DC';e={$dc}}, @{n='LastLogon';e={[DateTime]::FromFileTime($_.lastLogon)}}
}
한 번도 로그인하지 않은 계정은 LastLogonDate 가 비어 있어 조회에서 빠질 수 있으므로 따로 확인한다.
Get-ADUser -Filter * -Properties LastLogonDate, whenCreated |
Where-Object { -not $_.LastLogonDate -and $_.whenCreated -lt (Get-Date).AddDays(-90) }
먼저 목록을 파일로 남기고, 그 파일을 근거로 처리한다. 파이프로 바로 이어 붙이면 무엇을 껐는지 남지 않는다.
$targets = Search-ADAccount -AccountInactive -UsersOnly -TimeSpan 90.00:00:00 |
Where-Object { $_.Enabled -eq $true }
$targets | Select-Object SamAccountName, Name, LastLogonDate, DistinguishedName |
Export-Csv C:\temp\inactive_$(Get-Date -f yyyyMMdd).csv -NoTypeInformation -Encoding UTF8
$targets | Disable-ADAccount -WhatIf
-WhatIf 로 대상을 먼저 확인한 뒤 옵션을 빼고 실행한다.
서비스 계정과 내장 계정을 반드시 제외한다. 서비스 계정은 대화형 로그온을 하지 않아 LastLogonTimeStamp 가 갱신되지 않는 경우가 있고, 이런 계정을 끄면 연동이 한꺼번에 멈춘다. 제외 OU 를 지정하거나 이름 규칙으로 걸러 낸다.
$targets = $targets | Where-Object {
$_.DistinguishedName -notlike '*OU=ServiceAccounts,*' -and
$_.SamAccountName -notmatch '^(svc|krbtgt|Guest)'
}
비활성화한 계정을 별도 OU 로 옮겨 두면 나중에 되돌리기 쉽다.
$targets | Move-ADObject -TargetPath 'OU=Disabled,DC=example,DC=com'