PowerShell Version 1 script to find all accounts that are experiencing bad password attempts. The script finds all accounts where the badPwdCount attribute has a value greater than 0. This attribute is not replicated so every domain controller in the domain must be queried. For each account found on each domain controller the script outputs the values of the distinguishedName, sAMAccountName, logonCount, badPwdCount, and badPasswordTime attributes. The last three values are not replicated, so they will be different on every DC. The values are output in comma delimited format. If the output is redirected to a text file, the file can be opened in Microsoft Excel. The DC with the PDC Emulator role is identified by appending the string "(PDCe)". All bad password attempts are forwarded to the PDC Emulator.

 

PowerShell
Edit|Remove
# FindBadPwdAttempts.ps1 
# PowerShell Version 1 script to find all accounts that are experiencing 
# bad password attempts. The script finds all accounts where the badPwdCount 
# attribute has a value greater than 0. This attribute is not replicated 
# so every domain controller in the domain must be queried. 
# For each account found on each domain controller the script outputs 
# the values of the distinguishedName, sAMAccountName, logonCount, 
# badPwdCount, and badPasswordTime attributes. 
 
# Author: Richard L. Mueller 
# Version 1.0 - October 62015 
 
# Retrieve information for the current domain. 
$D = [system.directoryservices.activedirectory.Domain]::GetCurrentDomain() 
$PDC = $D.PdcRoleOwner 
$Domain = [ADSI]"LDAP://$D" 
 
# Setup the DirectorySearcher object. 
$Searcher = New-Object System.DirectoryServices.DirectorySearcher 
$Searcher.PageSize = 200 
$Searcher.SearchScope = "subtree" 
$Searcher.Filter = "(badPwdCount>=1)" 
# Specify attribute values to retrieve. 
$Searcher.PropertiesToLoad.Add("distinguishedName") > $Null 
$Searcher.PropertiesToLoad.Add("sAMAccountName") > $Null 
$Searcher.PropertiesToLoad.Add("badPwdCount") > $Null 
$Searcher.PropertiesToLoad.Add("badPasswordTime") > $Null 
$Searcher.PropertiesToLoad.Add("logonCount") > $Null 
 
# Output a heading line. 
"distinguishedName,sAMAccountName,logonCount,badPwdCount,badPasswordTime" 
 
# Query every domain controller in the domain. 
ForEach ($DC In $D.DomainControllers) 
{ 
    $Server = $DC.Name 
    $Results = $Null 
    # Identify the DC with the PDC Emulator role. 
    If ($Server -eq $PDC) {"=== DC: $Server (PDCe)"} 
    Else {"=== DC: $Server"} 
    # Specify the DC and the domain in the Base of the query. 
    $Base = "LDAP://$Server/" + $Domain.distinguishedName 
    $Searcher.SearchRoot = $Base 
    $Results = $Searcher.FindAll() 

    If($Results) 
    { 
        # Output one line for each account. 
        ForEach ($Result In $Results) 
        { 
            # Retrieve the values. 
            $DN = $Result.Properties.Item("distinguishedName") 
            $NTName = $Result.Properties.Item("sAMAccountName") 
            $BadCount = $Result.Properties.Item("badPwdCount") 
            $LogonCount = $Result.Properties.Item("logonCount") 
            $Time = $Result.Properties.Item("badPasswordTime") 
            $BadTime = ([DateTime]$Time.Item(0)).AddYears(1600).ToLocalTime() 
            # Output in comma delimited format. 
            """$DN"", $NTName, $LogonCount, $BadCount, $BadTime" 
        } 
    } 
    Else 
    { 
        Write-Host "ERROR: Failed to connect to DC $Server" -foregroundcolor red -backgroundcolor black 
        "<DC not found>" 
    } 
}