Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- [CmdletBinding()]Param(
- [Parameter()][switch]$EstimatedLogon
- )
- function GetRealLogonDate{
- [CmdletBinding()]
- Param(
- [Parameter(Mandatory=$true,
- Position=0)]
- [String]$sAMAccountName,
- [Parameter(Mandatory=$true,
- Position=1)]
- [String]$Domain
- )
- # Currenly not used, but may use some day. The idea is to get the 'real' last logon time of an account
- # before we apply a bogus to it.
- try{
- $domainContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('Domain',$Domain)
- $domainInfo = [DirectoryServices.ActiveDirectory.Domain]::GetDomain($domainContext)
- }
- catch{
- throw('Unable to connect to {0}: {1}' -f $Domain,$_.exception.message)
- }
- [array]$dcList = $domainInfo.DomainControllers | foreach { $_.name }
- Write-Verbose -Message ('[GetRealLogonDate] Found {0} DCs in {1}' -f $dcList.count,$Domain)
- $queryBlock = {
- Param(
- [Parameter(Mandatory=$true,
- Position=0)]
- [String]$sAMAccountName,
- [Parameter(Mandatory=$true,
- Position=1)]
- [String]$ComputerName
- )
- $searcher = new-object System.DirectoryServices.DirectorySearcher([ADSI]"LDAP://$ComputerName")
- $searcher.filter = "(&(objectClass=User)(lastlogon=*)(sAMAccountName=$sAMAccountName))"
- [void]$searcher.PropertiesToLoad.Add('lastlogon')
- try{
- $userObj = $searcher.FindOne()
- }
- catch{
- return $null
- }
- Write-Output $(New-Object -TypeName PSObject -Property @{DC=$ComputerName;sAMAccountName=$sAMAccountName;LastLogon=[int64]$($userObj.Properties.lastlogon | Out-String).trim()})
- }
- $queryQueue = New-Object System.Collections.ArrayList
- for($i = 0; $i -lt $dcList.count; $i++){
- Write-Verbose ('[GetRealLogonDate] Running jobs: {0}' -f (Get-Job -State Running).Count)
- While( (Get-Job -State Running).Count -ge 10 ){
- Start-Sleep -Seconds 3
- }
- Write-Verbose ('[GetRealLogonDate] Starting job for {0}' -f $dcList[$i])
- Start-Job -Name $dcList[$i] -ScriptBlock $queryBlock -ArgumentList $sAMAccountName,$dcList[$i] | Out-Null
- Get-Job -State Completed | Where { $_.Name -like "*.$Domain.*"} | Receive-Job -Wait -AutoRemoveJob | foreach { [void]$queryQueue.Add($_)}
- }
- Write-Verbose ('[GetRealLogonDate] Waiting for running jobs to finish')
- Get-Job | Wait-Job | Receive-Job -Wait -AutoRemoveJob | foreach { [void]$queryQueue.Add($_)}
- $log = 0
- for($q = 0; $q -lt $queryQueue.count; $q++){
- if($queryQueue[$q].LastLogon -like $null){continue}
- if($queryQueue[$q].LastLogon -gt $log){$log = $queryQueue[$q].LastLogon}
- }
- Write-Output $([datetime]::FromFileTime($log))
- }
- $users = Get-ADUser -Filter {Enabled -eq $true} -ResultSetSize 50000 -Properties displayName,description,PasswordLastSet,MemberOf,CanonicalName,LastLogonDate
- $UserReport = New-Object System.Collections.ArrayList
- foreach ($u in $users){
- if($EstimatedLogon){
- $lastLogon = $u.LastLogonDate
- }
- else{
- $lastLogon = GetRealLogonDate -sAMAccountName $u.sAMAccountName -Domain ($u.CanonicalName -split '/')[0]
- }
- $UserObject = New-Object -TypeName PSObject -Property @{
- sAMAccountName = $u.sAMAccountName
- displayName = $u.displayName
- description = $u.description
- LastLogon = $lastlogon
- PasswordLastSet = $u.PasswordLastSet
- Memberships = [string]::Join(';',($u.Memberof | foreach { ($_ -split ',')[0] -replace 'CN=' } | sort))
- }
- [void]$UserReport.Add($UserObject)
- }
- Write-Output $UserReport
Advertisement
Add Comment
Please, Sign In to add comment