Finding Old or Unused Accounts with Powershell

Recently I tried to find accounts that haven't been used in a long time. In order to do this I wrote a powershell script to get the last logon time for all accounts in the domain. The problem is, each domain controller contains a different time for the Last Logon depending on which was used as the logon server. In order to get an accurate time we need to get the last logon from each domain controller for each user. This is NOT a fast process. If there are 500 users and 4 domain controllers that is 2000 requests. On top of that some of the domain controllers might be a different location with a slower WAN link which will make it go even slower.

Note: This script requires Quest Software's Active Directory cmdlets. You can download it from here: http://www.quest.com/powershell/activeroles-server.aspx


Add-PSSnapIn Quest.ActiveRoles.ADManagement -ErrorAction SilentlyContinue

$dcs = Get-QADComputer -ComputerRole DomainController
$users = Get-QADUser -SizeLimit 0

#$ErrorActionPreference = "Continue"

foreach ($user in $users) {
    #"Searching $($user.Name)"
    $lastlogon = $null
    foreach ($dc in $dcs) { 
        $dclogon = (Get-QADUser -Service $dc.Name -SamAccountName $user.Name).LastLogon
        #"$($user.Name) $($dc.Name) $dclogon"
        if ($dclogon -ne $Null) {
            if ($lastlogon -lt $dclogon) {
                #write-host "replacing"
                $lastlogon = $dclogon
            }
        }
    }
    
    if ($lastlogon -eq $Null) { $lastlogon = [dbnull]::value }
    #"$($user.Name) $lastlogon"
    
    $o = New-Object PSObject
    $o | Add-Member NoteProperty "User" $user.Name
    $o | Add-Member NoteProperty "LastLogin" $lastlogon
    $o | Add-Member NoteProperty "DisplayName" $user.DisplayName
    $o | Add-Member NoteProperty "Disabled" ([ADSI]("LDAP://$($user.DN.ToString())")).PsBase.InvokeGet("AccountDisabled")
    $o | Add-Member NoteProperty "DistinguishedName" $user.DN
    $o | Add-Member NoteProperty "Title" $user.title
    $o | Add-Member NoteProperty "SamAccountName" $user.SamAccountName
    $o | Add-Member NoteProperty "LastName" $user.LastName
    $o | Add-Member NoteProperty "FirstName" $user.FirstName
    
    Write-Output $o
}

Assuming you put this script in the file Get-LastLogin.ps1 you can find all accounts that haven't logged in during the past 90 days.
.\Get-LastLogin.ps1 | where {$_.LastLogin -lt (Get-Date).AddDays(-90)}

If you want to sort the results and save it as a csv you can do this:
.\Get-LastLogin.ps1 | where {$_.LastLogin -lt (Get-Date).AddDays(-90)} | | Sort-Object @{expression="LastLogin";Descending=$true},@{expression="User";Ascending=$true} | Export-Csv "c:\lastloginreport.csv" -noTypeInformation

 del.icio.us  Stumbleupon  Technorati  Digg 

 

What did you think of this article?




Trackbacks
  • No trackbacks exist for this entry.
Comments

Leave a comment

Submitted comments will be subject to moderation before being displayed.

 Enter the above security code (required)

 Name

 Email (will not be published)

 Website

Your comment is 0 characters limited to 3000 characters.