PowerShell Script to Determine What Device is Locking Out an Active Directory User Account
I recently received a request to determine why a specific user account was constantly being locked out after changing their Active Directory password and while I've previously written scripts to accomplish this same type of task, I decided to write an updated script.
Active Directory user account lockouts are replicated to the PDC emulator in the domain through
emergency replication and while I could have used the Get-ADDomain
cmdlet to easily determine the
PDC emulator for the domain:
1(Get-ADDomain).PDCEmulator
That would have had a dependency of requiring the RSAT tools to be installed on the workstation this script was being run from so I decided to use the .NET framework to accomplish that particular task to eliminate the Active Directory module dependency:
1[System.DirectoryServices.ActiveDirectory.Domain]::GetDomain((
2 New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('Domain', $env:USERDNSDOMAIN))
3).PdcRoleOwner.name
If you're interested in using the .NET framework to determine the Active Directory FSMO role holders with PowerShell, I wrote a blog article titled PowerShell Function to Determine the Active Directory FSMO Role Holders via the .NET Framework that covers that subject in more detail.
This Get-LockedOutUser.ps1
script allows you to specify the following via parameter input to
narrow down the results:
- Specific userid, defaulting to all locked out userid's
- Start time to begin searching records for, defaulting to the last three days
- Domain name to search for lockouts in, defaulting to the user's domain who is running the script
1#Requires -Version 3.0
2<#
3.SYNOPSIS
4 Get-LockedOutUser.ps1 returns a list of users who were locked out in Active Directory.
5
6.DESCRIPTION
7 Get-LockedOutUser.ps1 is an advanced script that returns a list of users who were locked out in Active Directory
8by querying the event logs on the PDC emulator in the domain.
9
10.PARAMETER UserName
11 The userid of the specific user you are looking for lockouts for. The default is all locked out users.
12
13.PARAMETER StartTime
14 The datetime to start searching from. The default is all datetimes that exist in the event logs.
15
16.EXAMPLE
17 Get-LockedOutUser.ps1
18
19.EXAMPLE
20 Get-LockedOutUser.ps1 -UserName 'mikefrobbins'
21
22.EXAMPLE
23 Get-LockedOutUser.ps1 -StartTime (Get-Date).AddDays(-1)
24
25.EXAMPLE
26 Get-LockedOutUser.ps1 -UserName 'mikefrobbins' -StartTime (Get-Date).AddDays(-1)
27#>
28
29[CmdletBinding()]
30param (
31 [ValidateNotNullOrEmpty()]
32 [string]$DomainName = $env:USERDOMAIN,
33
34 [ValidateNotNullOrEmpty()]
35 [string]$UserName = "*",
36
37 [ValidateNotNullOrEmpty()]
38 [datetime]$StartTime = (Get-Date).AddDays(-3)
39)
40
41Invoke-Command -ComputerName (
42
43 [System.DirectoryServices.ActiveDirectory.Domain]::GetDomain((
44 New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('Domain', $DomainName))
45 ).PdcRoleOwner.name
46
47) {
48
49 Get-WinEvent -FilterHashtable @{LogName='Security';Id=4740;StartTime=$Using:StartTime} |
50 Where-Object {$_.Properties[0].Value -like "$Using:UserName"} |
51 Select-Object -Property TimeCreated,
52 @{Label='UserName';Expression={$_.Properties[0].Value}},
53 @{Label='ClientName';Expression={$_.Properties[1].Value}}
54
55} -Credential (Get-Credential) |
56Select-Object -Property TimeCreated, UserName, ClientName
The script prompts for alternate credentials because in my opinion, you shouldn't be running your PowerShell session with elevated credentials:
As you can see, jimmy0 is being locked out by a device named PC01:
The StartTime parameter can be used to specify more or fewer days if the default of three days doesn't meet your needs as shown in the following example where one day is used:
Update 08/30/15:
I've posted an updated version of this script which is now a PowerShell function that includes error handling that can be downloaded from my Active Directory repository on GitHub.
µ