How to: track the source of user account lockout using Powershell
In my last post about how to Find the source of Account Lockouts in Active Directory I showed a way to filter the event viewer security log with a nifty XML query.
In this post I recomposed (Source:Ian Farr) a Powershell script which will ask for the locked user account name and then will scan the active directory DCs security log for relevant events and will present the user lock time and source of the lock out like so:
Make sure you have the active directory module loaded on the machine you run the script from: Import-Module ActiveDirectory
You can add the import-module command to the top of the script if you like.
The script:
$ErrorActionPreference = "SilentlyContinue" Clear-Host $User = Read-Host -Prompt "Please enter a user name" #Locate the PDC $PDC = (Get-ADDomainController -Discover -Service PrimaryDC).Name #Locate all DCs $DCs = (Get-ADDomainController -Filter *).Name #| Select-Object name foreach ($DC in $DCs) { Write-Host -ForegroundColor Green "Checking events on $dc for User: $user" if ($DC -eq $PDC) { Write-Host -ForegroundColor Green "$DC is the PDC" } Get-WinEvent -ComputerName $DC -Logname Security -FilterXPath "*[System[EventID=4740 or EventID=4625 or EventID=4770 or EventID=4771 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}} -ErrorAction SilentlyContinue }
This script scans ALL Domain Controllers and not just the PDC as most people do. I found that sometimes a lockout event will appear in a different DC server, so to make sure you dont miss anything, its better in my opinion to scan all domain controllers and wait the extra time for the script to finish. However, in most cases lockout events will appear on the PDC server.
After you have found the source of user lockout, go to each PC and disconnect the session or look for running scheduled tasks or scripts under this user context. Rebooting the locking PC if possible, is also a good practice.
⇒
Here is another script contributed by Alexandre Almeida on the same topic.
#script written by Alexandre Almeida # for get user Account Lockout Host name $username = Read-Host "Please Enter the Locked User Name: " $DCCounter = 0 $LockedOutStats = @() Try { Import-Module ActiveDirectory -ErrorAction Stop } Catch { Write-Warning $_ Break } #Get all domain controllers in domain $DomainControllers = Get-ADDomainController -Filter * $PDCEmulator = ($DomainControllers | Where-Object {$_.OperationMasterRoles -contains "PDCEmulator"}) Write-Verbose "Finding the domain controllers in the domain" Foreach($DC in $DomainControllers) { # $DCCounter++ # Write-Progress -Activity "Contacting DCs for lockout info" -Status "Querying $($DC.Hostname)" -PercentComplete (($DCCounter/$DomainControllers.Count) * 100) Write-Verbose "Finding the Which domain controllers Authenticate the Password" Try { $UserInfo = Get-ADUser -Identity $username -Server $DC.Hostname -Properties LastLogonDate -ErrorAction Stop Write-Verbose "Bad Password Attempt count collected" } Catch { # Write-Warning $_ Continue } If($UserInfo.LastBadPasswordAttempt) { $LockedOutStats += New-Object -TypeName PSObject -Property @{ Name = $UserInfo.SamAccountName SID = $UserInfo.SID.Value LockedOut = $UserInfo.LockedOut BadPwdCount = $UserInfo.BadPwdCount BadPasswordTime = $UserInfo.BadPasswordTime DomainController = $DC.Hostname AccountLockoutTime = $UserInfo.AccountLockoutTime LastLogonDate = ($UserInfo.LastLogonDate).ToLocalTime() } }#end if }#end foreach DCs $LockedOutStats | Format-Table -Property Name,LockedOut,DomainController,BadPwdCount,AccountLockoutTime,LastBadPasswordAttempt -AutoSize #Get User Info Try { Write-Verbose "Querying event log on $($PDCEmulator.HostName)" Write-Verbose "Collecting Event Log" $LockedOutEvents = Get-WinEvent -ComputerName $PDCEmulator.HostName -FilterHashtable @{LogName='Security';Id=4740} -ErrorAction Stop | Sort-Object -Property TimeCreated -Descending } Catch { Write-Warning $_ Continue }#end catch Foreach($Event in $LockedOutEvents) { If($Event | Where {$_.Properties[2].value -match $UserInfo.SID.Value}) { $Event | Select-Object -Property @( @{Label = 'User'; Expression = {$_.Properties[0].Value}} @{Label = 'DomainController'; Expression = {$_.MachineName}} @{Label = 'EventId'; Expression = {$_.Id}} @{Label = 'LockedOutTimeStamp'; Expression = {$_.TimeCreated}} @{Label = 'Message'; Expression = {$_.Message -split "`r" | Select -First 1}} @{Label = 'LockedOutLocation'; Expression = {$_.Properties[1].Value}} ) Write-host $_.MachineName }#end ifevent }#end foreach lockedout event Write-Verbose "Collected Details Update in the Text File. Please find the Text file for More Details" echo "Cache Profile Removal Steps 1) Open Control Panel > Credential Manager > Remove all Saved Password. 2) Remove passwords by clicking on Start => Run => type (rundll32.exe keymgr.dll KRShowKeyMgr) without quotes and then delete the Domain-related passwords; 3) Remove passwords in Internet Explorer => Tools => Internet Options =>Content => Personal Information => Auto Complete => Clear Passwords; 4) Delete cookies in Internet Explorer => Tools => Internet Options =>General; 5) Disconnect (note the path before disconnecting) all networks drives, reboot, then map them again; 6) Start -> run ->type control userpasswords2 without quotes and go to advanced -> Manage passwords and remove all the stored passwords. 7) Reconfigure Your mobile Setting if your Active sync enabled. 8) Check if any saved or scheduled task is configured for user account Microsoft Kwoledge Bytes Link for Cache profile Removal Steps: https://social.technet.microsoft.com/Forums/windows/en-US/ced8eab6-87e2-4d20-9d18-7aaf5e9713a3/windows-7-clear-cached-credentials"
i took the liberty to modify the script a little to make a graphic Display of the results and the help information at the end.
#script written by Alexandre Almeida
#modified by Roberth Zelaya
Add-Type -AssemblyName System.Windows.Forms
Clear-Host
#ask for elevation if needed
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] “Administrator”)) { Start-Process powershell.exe “-NoLogo -WindowStyle hidden -NoProfile -ExecutionPolicy Bypass -File `”$PSCommandPath`”” -Verb RunAs; exit
}
$list = Search-ADAccount -lockedout | Select-Object Name, SamAccountName, LastLogonDate, Enabled, DistinguishedName
$username = $list |select -ExpandProperty SamAccountName
$DCCounter = 0
$LockedOutStats = @()
Try
{
Import-Module ActiveDirectory -ErrorAction Stop
}
Catch
{
Write-Warning $_
Break
}
#Get all domain controllers in domain
$DomainControllers = Get-ADDomainController -Filter *
$PDCEmulator = ($DomainControllers | Where-Object {$_.OperationMasterRoles -contains “PDCEmulator”})
Write-Verbose “Finding the domain controllers in the domain”
Foreach($DC in $DomainControllers)
{
# $DCCounter++
# Write-Progress -Activity “Contacting DCs for lockout info” -Status “Querying $($DC.Hostname)” -PercentComplete (($DCCounter/$DomainControllers.Count) * 100)
Write-Verbose “Finding the Which domain controllers Authenticate the Password”
Try
{
$UserInfo = Get-ADUser -Identity $username -Server $DC.Hostname -Properties LastLogonDate -ErrorAction Stop
Write-Verbose “Bad Password Attempt count collected”
}
Catch
{
# Write-Warning $_
Continue
}
If($UserInfo.LastBadPasswordAttempt)
{
$LockedOutStats += New-Object -TypeName PSObject -Property @{
Name = $UserInfo.SamAccountName
SID = $UserInfo.SID.Value
LockedOut = $UserInfo.LockedOut
BadPwdCount = $UserInfo.BadPwdCount
BadPasswordTime = $UserInfo.BadPasswordTime
DomainController = $DC.Hostname
AccountLockoutTime = $UserInfo.AccountLockoutTime
LastLogonDate = ($UserInfo.LastLogonDate).ToLocalTime()
}
}#end if
}#end foreach DCs
$LockedOutStats | Format-Table -Property Name,LockedOut,DomainController,BadPwdCount,AccountLockoutTime,LastBadPasswordAttempt -AutoSize
#Get User Info
Try
{
Write-Verbose “Querying event log on $($PDCEmulator.HostName)”
Write-Verbose “Collecting Event Log”
$LockedOutEvents = Get-WinEvent -ComputerName $PDCEmulator.HostName -FilterHashtable @{LogName=’Security’;Id=4740} -ErrorAction Stop | Sort-Object -Property TimeCreated -Descending
}
Catch
{
Write-Warning $_
Continue
}#end catch
$Results =@()
Foreach($Event in $LockedOutEvents)
{
If($Event | Where {$_.Properties[2].value -match $UserInfo.SID.Value})
{
$Information = $Event | Select-Object -Property @(
@{Label = ‘User’; Expression = {$_.Properties[0].Value}}
@{Label = ‘DomainController’; Expression = {$_.MachineName}}
@{Label = ‘EventId’; Expression = {$_.Id}}
@{Label = ‘LockedOutTimeStamp’; Expression = {$_.TimeCreated}}
@{Label = ‘Message’; Expression = {$_.Message -split “`r” | Select -First 1}}
@{Label = ‘LockedOutLocation’; Expression = {$_.Properties[1].Value}}
)
# Write-host $_.MachineName
}#end ifevent
$Results += $Information #add Results to Array for display
}#end foreach lockedout event
$display = $Results
$display | Out-GridView -Title “Lockout information”
$popUp=[System.Windows.Forms.MessageBox]::Show(“Display Recommendations?” , “Information”,’OKCancel’, “Information”)
if($popUp-eq “Ok”)
{
Display_Information
}
function Display_Information()
{
$MessageBody = “1) Open Control Panel > Credential Manager > Remove all Saved Password.`n
2) Remove passwords by clicking on Start => Run => type (rundll32.exe keymgr.dll KRShowKeyMgr) without quotes and then delete the Domain-related passwords;`n
3) Remove passwords in Internet Explorer => Tools => Internet Options =>Content => Personal Information => Auto Complete => Clear Passwords;
4) Delete cookies in Internet Explorer => Tools => Internet Options =>General;`n
5) Disconnect (note the path before disconnecting) all networks drives, reboot, then map them again;`n
6) Start -> run ->type control userpasswords2 without quotes and go to advanced -> Manage passwords and remove all the stored passwords.`n
7) Reconfigure Your mobile Setting if your Active sync enabled.`n
8) Check if any saved or scheduled task is configured for user account.`n
Microsoft Kwoledge Bytes Link for Cache profile Removal Steps:`n”
$link=”https://social.technet.microsoft.com/Forums/windows/en-US/ced8eab6-87e2-4d20-9d18-7aaf5e9713a3/windows-7-clear-cached-credentials”
[System.Windows.Forms.MessageBox]::Show(“$MessageBody” , “Cache Profile Removal Steps”,’OK’, “Information”)
$validation= $link | Out-GridView -Title “Lockout information” -PassThru
if($validation -eq $null)
{
exit
}
else{
Start-Process($link)
}
}
Amazing Script
Thank you alot