Tracing the Source of Account Lockouts

As an Active Directory administrator, you have no doubt experienced re-occurring account lockouts. Back in the day, you would need the investigative powers of a Mr Sherlock Holmes to get to the bottom of these little mysteries! Then, the Account Lockout Tools made the process somewhat easier. Now, though, we have the magnificence of PowerShell…

From Windows Server 2008 onwards, an account lockout event will register on the PDCe as event ID 4740 – ‘a user account was locked out’ – with the lockout source included. All we then need to do is collect these events!

Here’s the sample code:

#Obtain user

$User = Read-Host -Prompt “Please enter a user name”

#Specify PDCe

$PDC = Get-ADDomainController -Discover -Service PrimaryDC

#Collect lockout events for user from last hour

Get-WinEvent -ComputerName $PDC `

-Logname Security `

-FilterXPath “*[System[EventID=4740 and TimeCreated[timediff(@SystemTime) <= 3600000]] and EventData[Data[@Name=’TargetUserName’]=’$User‘]]” |

Select-Object TimeCreated,@{Name=‘User Name’;Expression={$_.Properties[0].Value}},@{Name=‘Source Host’;Expression={$_.Properties[1].Value}}


The ‘Obtain user’ section uses Read-Host to prompt the operator for a user account that is locked out. The supplied name is then stored in $User for later use.

The ‘Specify PDCe’ section uses the Get-ADDomainController cmdlet, with its -Discover parameter, to locate the domain’s PDCe. The domain controller found by the dclocator process is then stored in $PDC.

The final section moves up a gear or two. The Get-WinEvent cmdlet connects to the PDCe and looks at the Security log. A filter is then applied, using the XPath language. This language lets you do some really cool stuff with XML documents (from Windows Server 2008 onwards, events are stored as XML).

Let’s break the expression down. We’re first going to join and match two conditions from the ‘System’ node within each XML entry:

  • the first condition is easy, ‘EventID=4740’ – this matches any 4740 events
  • the second makes sure we collect events from the last hour – ‘TimeCreated[timediff(@SystemTime) <= 3600000]

Next, we join the first two conditions to a third matched condition from the ‘EventData node’:

  • EventData[Data[@Name=’TargetUserName’]=’$User’] – we look ‘TargetUserName’ and make sure it matches our supplied user name, stored in $User

Once we’ve matched all three conditions from the XPath expression, we pass any resultant, filtered objects on to the Select-Object cmdlet. Here, the time the event was created is displayed along with two custom headers. Let’s look at one of them in more detail:

@{Name=‘User Name’;Expression={$_.Properties[0].Value}}

Here, we create a header called ‘User Name’ and populate it with the first element from an array of the event’s properties. The next Select-Object expression does something very similar, creating a header called ‘Source Host’ and populating it with the second element from the ‘Properties’ array.

Here’s some sample output:



Again, PowerShell makes life’s little administrative tasks much, much easier!

Finally, with the source host identified, experience tells me to look for stale RDP sessions, mapped drives, schedules tasks, etc., etc…


Comments (21)

  1. Ed (DareDevil57) says:


  2. If you get RPC errors, in the first instance, update Get-WinEvent -ComputerName $PDC to Get-WinEvent -ComputerName $PDC.Name… after that, you’re on your own 😉

    1. Anonymous says:

      Thanks, This helped me so much after my account kept constantly locking out. This found the source of the issue and voila… all sorted now.

  3. Put it all on one line and then see if you get the same result…

  4. Anonymous says:

    Pingback from AD: Tracing the Source of Account Lockouts | MS Tech BLOG

  5. Brett Holden says:

    I've been looking for an easy way to do this for some time. This is spot-on, thanks

  6. Excellant and helped me to find the account lockout for DGM

  7. Mahesh Adate says:

    Dear Ian Farr,

    If possible, Please create a script file to download and execute.

  8. Joe says:

    Oh my god, just copy the content, paste it into notepad and save it.

    1. Andrew says:

      Should I just copy this as is and save it as a VBS?

  9. Greg D says:

    Tried to run this, but it just prints out ALL of the events form my PDC to the screen. Can't see anything relating to account lockouts or even related to the user account. Any ideas?

  10. Greg C says:

    Everything after "#Collect lockout events for user from last hour" is a single line

  11. Vinny says:

    What if we need to check before 15 to 20 days

  12. jbruns2010 says:

    Not only do we need machine, but what process on that machine. If it’s not obvious, it can be very hard to know.

  13. jbruns2010 says:

    We used to be able to use ALockout.dll in 2003 but it no longer works in 2008 and up.

  14. sreenivasa sarma says:

    my traces account is locked how to lockout

  15. Andy says:

    Hi, this script is brilliant thank you but it runs incredibly slow, does anybody else experience this or is it something I can remedy?

  16. rino19ny says:

    strange i couldn’t get that output:

    ProviderName: Microsoft-Windows-Security-Auditing

    TimeCreated Id LevelDisplayName Message
    ———– — —————- ——-
    11/30/2016 10:34:30 AM 4624 Information An account was successfully logged on….
    11/30/2016 10:34:30 AM 4768 Information A Kerberos authentication ticket (TGT) was requested….
    11/30/2016 10:34:30 AM 4634 Information An account was logged off….
    11/30/2016 10:34:30 AM 4634 Information An account was logged off….

  17. Wolfgang says:

    “Get-WinEvent : The specified query is invalid” 🙁

    1. Karl says:

      Same error for me

Skip to main content