An account locks out repeatedly and nobody knows why
Something is presenting an old password over and over. The lockout event names the machine it came from, which is the whole investigation.
What you see
A user is locked out minutes after every unlock. Event 4740 on the PDC emulator. The user insists they are typing the right password, and they usually are.
What is actually wrong
A cached credential somewhere — a mapped drive, a scheduled task, a service account, a phone's mail profile, or a stale RDP session on a server.
Codes and articles
The fix
Trace the lockout to its source
Any repeated lockout. Every lockout is recorded centrally, so this is a lookup rather than a hunt.
Every lockout is written to the PDC emulator. Read the events and the caller machine name.
$pdc = (Get-ADDomain).PDCEmulatorGet-WinEvent -ComputerName $pdc -FilterHashtable @{LogName='Security'; Id=4740} -MaxEvents 20 | ForEach-Object { $x=[xml]$_.ToXml(); [PSCustomObject]@{ Time=$_.TimeCreated; User=$x.Event.EventData.Data[0].'#text'; Caller=$x.Event.EventData.Data[1].'#text' } } | Format-Table -AutoSize
The Caller field is the machine that sent the bad password. It is the single most useful piece of information in the whole investigation and it is right there in the event.
If the caller is blank or a domain controller, the request came in over Kerberos — check 4771 for the client address.
Get-WinEvent -ComputerName $pdc -FilterHashtable @{LogName='Security'; Id=4771} -MaxEvents 30 | ForEach-Object { $x=[xml]$_.ToXml(); [PSCustomObject]@{ Time=$_.TimeCreated; User=$x.Event.EventData.Data[0].'#text'; Address=$x.Event.EventData.Data[6].'#text' } } | Format-Table -AutoSizeCheck the lockout status across all DCs to confirm where it originates.
Search-ADAccount -LockedOut | Format-Table Name, SamAccountName, LastLogonDate -AutoSizeGet-ADUser jbloggs -Properties LockedOut, BadLogonCount, LastBadPasswordAttempt | Format-List
On the caller machine, clear the stored credentials.
cmdkey /listcmdkey /delete:example.local
Check scheduled tasks and services running as that account.
Get-ScheduledTask | Where-Object { $_.Principal.UserId -like '*jbloggs*' } | Format-Table TaskName, TaskPath -AutoSizeGet-CimInstance Win32_Service | Where-Object StartName -like '*jbloggs*' | Format-Table Name, StartName -AutoSize
Log off any disconnected RDP sessions on servers — they hold the old token indefinitely.
quser /server:APPSRV01logoff 3 /server:APPSRV01
Get-ADUser jbloggs -Properties LockedOut, BadLogonCount | Format-List Name, LockedOut, BadLogonCountRelated faults
Where this stops. This write-up was written and checked by hand. It says what each step changes, how to confirm it worked and how to reverse it, and anything destructive is flagged before you reach it. If it does not match what your machine is doing, search the Support Centre for the exact code or message — and when something needs a person, get in touch.