All,
I have created the following PS script which extracts the following AD attribs from each DC, so you can select inactive accounts:
samaccountname, lastlogon, pwdlastset, lastlogontimestamp
I have tested this on PS2.0 agaist Win2003 & Win2008R2 DCs.
If you can see any improvments or changes that would make it better, I would love to know:
#Get all domain controllers for the current domain $StrDCs = [System.DirectoryServices.ActiveDirectory.Domain]::getcurrentdomain() | foreach{$_.DomainControllers| foreach{$_.Name}} $StrAllResults = $null $StrDCs | foreach-object { $Erroractionpreference = "Silentlycontinue" $strFilter = "(&(objectCategory=person)(objectClass=user))" $StrEachDC = "LDAP://"+$_.split(".")[0] $objDomain = New-Object System.DirectoryServices.DirectoryEntry $StrEachDC $objSearcher = New-Object System.DirectoryServices.DirectorySearcher $objSearcher.SearchRoot = $objDomain $objSearcher.PageSize = 100 $objSearcher.Filter = $strFilter $objSearcher.SearchScope = "Subtree" $strProps = "samaccountname,lastlogon,pwdlastset,lastlogontimestamp" $strProps.split(",") | %{[void]$objSearcher.PropertiesToLoad.Add($_);} $StrResults = $objSearcher.findall() $Erroractionpreference = "Continue" $StrAllResults += $StrResults Write-host "Finshed extracting information from $_" } # Group Account per samaccountName $StrAllResultsGrouped = $null $StrAllResultsGrouped = $StrAllResults | Group {$_.Properties.samaccountname}
# Format results at get date values $StrAllResultsMostRecentPerDC = $null $StrAllResultsMostRecentPerDC = $StrAllResultsGrouped | Foreach-object {$_.Group | Foreach-object ` { $_ | Select-Object ` @{n="LogonDomainController";Expression={($_ | select path).path.split("/")[2]}}, @{n="samaccountname";Expression={$_.properties.samaccountname}}, @{n="pwdlastset";Expression={"{0:dd/MM/yyyy HH:mm}" -f ([datetime]::fromfiletime([string]($_.Properties.pwdlastset)))}}, @{n="lastlogon";Expression={"{0:dd/MM/yyyy HH:mm}" -f ([datetime]::fromfiletime([string]($_.Properties.lastlogon)))}}, @{n="Lastlogontimestamp";Expression={"{0:dd/MM/yyyy HH:mm}" -f ([datetime]::fromfiletime([string]($_.Properties.lastlogontimestamp)))}} } } # Only select the most recent pwdlastset,lastlogon & Lastlogontimestamp for each samaccountname $StrAllResultsMostRecent = $null $StrAllResultsMostRecent = $StrAllResultsMostRecentPerDC | Group {$_.samaccountname} | Foreach-object ` { $StrTemp = @();$_.Group | Foreach-object {$StrTemp += $_} "" | Select-Object ` @{n="samaccountname";Expression={ $StrTemp[0].samaccountname}}, @{n="pwdlastset";Expression={($StrTemp | Select-Object pwdlastset | Sort-Object {[datetime]::ParseExact($_.pwdlastset,'dd/MM/yyyy HH:mm',$null)} -Descending | Select-Object -First 1).pwdlastset }}, @{n="lastlogon";Expression={($StrTemp | Select-Object lastlogon | Sort-Object {[datetime]::ParseExact($_.lastlogon,'dd/MM/yyyy HH:mm',$null)} -Descending | Select-Object -First 1).lastlogon }}, @{n="Lastlogontimestamp";Expression={($StrTemp | Select-Object Lastlogontimestamp | Sort-Object {[datetime]::ParseExact($_.Lastlogontimestamp,'dd/MM/yyyy HH:mm',$null)} -Descending | Select-Object -First 1).Lastlogontimestamp}} } Write-Host "Total account in AD: "$StrAllResultsMostRecent.count
#Selecting only accounts that have not logged on for 30 days $StrAllResultsInActiveAccount = $StrAllResultsMostRecent | Where-Object {[datetime]::ParseExact($_.lastlogon,'dd/MM/yyyy HH:mm',$null) -le (date).adddays(-30)} Write-Host "Total accounts that have not logged onto AD in 30 days: "$StrAllResultsInActiveAccount.count # Do something with these AD account: $StrAllResultsInActiveAccount
Cheers James
|