If a user account gets locked out, I can follow these tips to find out why and when it happened. But how can I check and gather lockout info along with the bad password attempts info of all users across the entire AD domain?
Asking help from PowerShell is my answer.
There are two places where we can gather this information. The AD contains the bad password attempts and the lockout status while the security event log saves the user account lockout information when it happens.
To get bad password attempts info from AD, use Get-ADUser cmdlet.
Get-ADUser -Filter * -Properties AccountLockoutTime,LastBadPasswordAttemptBadPwdCount,LockedOut
If you want just the info for the past day, pipe the result to Where clause.
Get-ADUser -Filter * -Properties AccountLockoutTime,LastBadPasswordAttemptBadPwdCount,LockedOut | Where {$_.LastBadPasswordAttempt -gt (Get-Date).AddDays(-1)}
To get the account lockout info, use Get-EventLog cmd to find all entries with the event ID 4740. Use -After switch to narrow down the date.
Get-EventLog -LogName "Security" -ComputerName "AD_Server" -After (Get-Date).AddDays(-1) -InstanceID "4740" | Select TimeGenerated, ReplacementString
Depending on the size of the log file, it could take a while to get all the result.
Going through the result, you may find the data shown on the screen is incomplete. That’s because the ReplacementString is a string array that contains the event log data in an XML type of format. Each event type has its own string structure. For 4740 events,
- ReplacementString[0] stores the name of the computer where the account gets locked out and
- ReplacementString[1] indicates the name of the user account that gets locked out.
So, instead of running the above cmdlet, the following script provides a lot more clear useful info.
#Collect lockout accounts from ADS
$logname = "security"
$dcname = (Get-AdDomain).pdcemulator
$eventID = "4740"
$content = Get-EventLog -LogName $logname -ComputerName $dcname -After (Get-Date).AddDays(-1) -InstanceId $eventID | Select TimeGenerated, ReplacementStrings
$ofs = "`r`n`r`n"
$body = "Fetching event log started on " + (Get-Date) + $ofs
If ($content -eq $null)
{
$body = $body + "No lock-out accounts happened today" + $ofs
}
Else
{
Foreach ($event in $content)
{
$source = $content.ReplacementStrings[1]
$username = $content.ReplacementStrings[0]
$body = $body + $event.TimeGenerated + ": " + $username + " - " + $source + $ofs
}
}
$body
Hope it helps.
Thanks for the post, really helpful.
btw: there should be a comma in LastBadPasswordAttemptBadPwdCount
thank you good information!
Get-winevent should be used instead.
Yes, indeed, if you are on PowerShell 7.
CASSE LES COUILLES TES PUBS, 1 clic n’importe ou ouvre une popup
Is there a way to get the IP Address of the last-bad-attempt?
It’s great to know “when”, but that doesn’t tell me much.
anyone get the IP address yet?
this is a nice script but not sure it has an output to where the issue may lie
hard to tell as no one locked out today
any advice on a script to hunt down where locked out source is?
thanks