So an Active Directory account lockout is something that is frequently happening for a user of yours. It can be frustrating if out of the blue, they’re just using Outlook, or even away from their desk and the account locks out.
I had a user get so bad that the lockouts would occur every 30 minutes to an hour. To add to his frustration, they had to keep on calling the help desk to unlock the account. It was an inconvenience to them and the help desk to say the least. So by now the question you might be asking yourself is.. How do we find out what is locking out an active directory account?
The quick answer once again is Powershell and Get-WinEvent.
Table Of Contents
- Active Directory Account Lockout Policies
- Find Active Directory Account Lockout Source
- Prerequisites
- Powershell Account Lockout Report Script
- Remove Passwords from the Credential Manager
- Removing Cached Credentials From KRShowKeyMgr
- Remove User Certificates from machine
- Disable Windows Hello Sign-in
- Unjoin and Rejoin Machine to the Domain
- How to run the script
- Conclusion
Active Directory Account Lockout Policies
I would imagine by now your domain should have something in place for passwords and account lockout policies. Those policies should include how many times a bad password can be entered before the account locks out. Another one would be after the how long the account gets auto-unlocked when it does get locked out. In the organizations I’ve been in, 5 bad password attempts and 30 minutes auto-unlock seem to have been the norm.
When configuring these policies, you also have to keep in the mind the security measures it may pose to a potential hacker. If you keep the threshold too low, they may be able to use that to their advantage. However, Security and Risk Management are always something to keep in the back of your mind but today we’re more focused on a way to find account lock out sources.
Find Active Directory Account Lockout Source
In Windows Server 2008, 2012 (R2) and 2016 every account lockout gets recorded with the EventID 4740. This is extremely useful for troubleshooting because we can go directly to the domain controller, filter for EventID 4740 and it will be able to give us some indication as to what’s locking out the account. The problem however, as I have encountered from personal experiences, is that it doesn’t get logged on every DC. Sometimes the PDC doesn’t even contain the events.
Therefore my script reiterates through all the DCs in your domain by default and spits out the users that have been locked out, I’ve also implemented the option to specify a single or multiple DC’s of your choosing. Not only that, I’ve even created a parameter to filter out a specific user in the event you don’t want other information. Dynamic filtering is key here and it’s why I love Powershell so much.
Prerequisites
Sort of – In order to be able to access the remote event logs, you first need to allow Inbound Firewall Rule for Remote Event Log Management. You can either go into each DC and allow an inbound firewall rule manually OR you can set it through GPO. I chose the latter for simplicity sake.
- To set the GPO, open Group Policy editor
- Navigate to Computer Configuration -> Policies -> Windows Settings -> Security Settings -> Windows Firewall with Advanced Security -> Inbound Rules.
- Create a new inbound rule
- select Remote Event Log Management from the predefined selection
- Next through the wizard to add the FW rules
Powershell Account Lockout Report Script
I’ll start off by saying that in order to query any domain controller, you’re going to need Domain Admin rights. Otherwise, you’re going to an access denied error. So let’s assume in this example that you have DA privileges and we’ll move on. So now the script:
#requires -Module ActiveDirectory Function Get-AccountLockoutStatus { <# .Synopsis This will iterate through all your domain controllers by default and checks for event 4740 in event viewer. To use this, you must dot source the file and call the function. For updated help and examples refer to -Online version. .DESCRIPTION This will go through all domain controllers by default and check to see if there are event ID for lockouts and display the information in table with Username, Time, Computername and CallerComputer. For updated help and examples refer to -Online version. .NOTES Name: Get-AccountLockoutStatus Author: theSysadminChannel Version: 1.01 DateCreated: 2017-Apr-09 DateUpdated: 2017-Apr-09 .LINK https://thesysadminchannel.com/get-account-lock-out-source-powershell - .PARAMETER ComputerName By default all domain controllers are checked. If a ComputerName is specified, it will check only that. .PARAMETER Username If a username is specified, it will only output events for that username. .PARAMETER DaysFromToday This will set the number of days to check in the event logs. Default is 3 days. .EXAMPLE Get-AccountLockoutStatus Description: Will generate a list of lockout events on all domain controllers. .EXAMPLE Get-AccountLockoutStatus -ComputerName DC01, DC02 Description: Will generate a list of lockout events on DC01 and DC02. .EXAMPLE Get-AccountLockoutStatus -Username Username Description: Will generate a list of lockout events on all domain controllers and filter that specific user. .EXAMPLE Get-AccountLockoutStatus -DaysFromToday 2 Description: Will generate a list of lockout events on all domain controllers going back only 2 days. #> [CmdletBinding()] param( [Parameter( ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [string[]] $ComputerName = (Get-ADDomainController -Filter * | select -ExpandProperty Name), [Parameter()] [string] $Username, [Parameter()] [int] $DaysFromToday = 3 ) BEGIN { $Object = @() } PROCESS { Foreach ($Computer in $ComputerName) { try { $EventID = Get-WinEvent -ComputerName $Computer -FilterHashtable @{Logname = 'Security'; ID = 4740; StartTime = (Get-Date).AddDays(-$DaysFromToday)} -EA 0 Foreach ($Event in $EventID) { $Properties = @{Computername = $Computer Time = $Event.TimeCreated Username = $Event.Properties.value[0] CallerComputer = $Event.Properties.value[1] } $Object += New-Object -TypeName PSObject -Property $Properties | Select ComputerName, Username, Time, CallerComputer } } catch { $ErrorMessage = $Computer + " Error: " + $_.Exception.Message } finally { if ($Username) { Write-Output $Object | Where-Object {$_.Username -eq $Username} } else { Write-Output $Object } $Object = $null } } } END {} }
Example 1: Get-AccountLockoutStatus
Example 2: Get-AccountLockoutStatus -Username DJones
Example 3: Get-AccountLockoutStatus -ComputerName PAC-DC01
Once you have run the script, you should notice the CallerComputer column because this is the source computer of the account lock outs. You can either go into the credential manager and remove all cached creds of the system, or simply see what’s happening with the computer.
In this article I manufactured the lockouts manually so nothing is going to show up in my credential manager.
How to Remove Passwords from the Credential Manager
In Windows 10 and Windows 7 alike, you can open up the Control Panel, sort by large icons (or small icons) and select Credential Manager from the list. From there you can click on the down arrow to expand the credential information and select Remove from Vault.
Removing Cached Credentials Using rundll32.exe keymgr.dll, KRShowKeyMgr
rundll32.exe keymgr.dll, KRShowKeyMgr is the command line version of Credential Manager and can sometimes have an extra cached credential that the GUI version might now show. As I look at my laptop now, I see an extra entry that I didn’t see in my GUI cred mgr.
To get started with this, open a command prompt and type rundll32.exe keymgr.dll, KRShowKeyMgr exactly as shown. It is case sensitive so it’s best to just copy and paste.
Remove any credentials that you think might be an issue. I noticed on my machine that I had an expired Communications Certificate. It wasn’t necessarily causing issues with my account but it’s something that could have been a potential issue if it was still sending those credentials to the Domain Controller.
Remove User Certificates from machine
Sometimes there can be some expired/misused certificates that can cause all types of problem. Thus, I would suggest removing any user certificates from the users computer. To do that go to start and type mmc.exe
- Within your MMC console go to File -> Add/Remove Snapin -> Certificates and click Add.
- Select My User Account. Click Finish and Click Ok to exit out of the Add/Remove Snap-Ins Wizard.
- Under Personal -> Certificates: Remove any expired certificates or anything that you think maybe causing issues.
Remove or Disable Windows Hello Sign-in
I have personally witnessed Windows Hello, specifically facial recognition, cause random Lockouts for end users. After spending hours and hours of troubleshooting, I threw a hail-mary and removed all Windows Hello sign-ins for said user and sure enough, after about 30 minutes we checked the logs and there were zero bad password attempts. Since I removed Windows Hello from the users computer, there has yet to be any lockouts for that account. A glorious win for me.
Unjoin and Rejoin Machine to the Domain
I have had success with unjoining and rejoining the machine to the domain to help solve Active Directory Lockout issues. To be perfectly honest, I don’t have the slightest clue why. Perhaps it might be that a certificate could have been revoked or maybe something was just stuck in limbo. But in a last ditch effort, try removing the computer account and adding back to the domain to hopefully resolve the account lockouts. It’s a troubleshooting step that sometimes cannot be overlooked.
How to run the script
In order to the run the script there are a couple of things you need to do. First and foremost, you need to set your execution policy to RemoteSigned. This is a standard with running any Powershell script.
Next you need to dot source the script since it is a function. To dot source the script do the following:
- Copy the script above and save it any location. In this example I’ll save it to my C:\_Scripts folder.
- Within the Powershell Window type: . .\_Scripts\Get-AccountLockoutStatus.ps1 – Note the two dots before the backslash.
Conclusion
Hopefully this article has helped you to track down the Active Directory account lockout source. Let me know what you think. Also, consider subscribing to our Youtube Channel to get video demos and other related sysadmin content.
Does the script scan all PCs in the domain?
It only checks the domain controllers for those event ids
The script worked really well for me. I spent hours trying to track down the source of my account lock out. it took about 2 minutes to set up to run the script and about a minute for it to return the offending computer. This was a really big help, Thanks!!
the script returns nothing. no errors, no results, it doesn’t even run long enough to be working.
it looks like it should work but doesn’t do anything. i guess that’s better than crashing the system or something.
I can run individual get-winevents so the connection *should* work.
also, what does the “-EA 0” on the get-winevent line do? I cant find that anywhere.
ErrorAction 0. On Error output nothing basically.
Thanks for sharind !