Get lockout source for currently locked users

lockout source

Todays articile is about getting lockout source and checking who is currently locked in your environment. Script is based on ActiveDirectory module and Get-WinEvent commands.

Currently locked users

First we need to check how many users are locked. Below you can find simple script for checking that. Script is using Search-ADAccount command with LockedOut parameter.

    #Setup arrays
    $LockedUsers = @()

    #=======================================================================
    #Checking locked users
    Search-ADAccount -LockedOut | select -first 10 | foreach{
        $City = $Object = $Null
        $City = (Get-ADUser -Identity $_.name -Properties City).City
        $Object = New-Object PSObject -Property ([ordered]@{ 
            Name         = $_.name
            Locked       = $_.lockedout
            Location     = $City
            UPN          = $_.UserPrincipalName        
        })
        $LockedUsers += $Object
    }
    "Currently locked users:"
    $LockedUsers | Format-Table -AutoSize -Wrap
locked users
locked users
Find lockout source

Next part is to find lockout source for each users. To do this we need check PDC server name and get events (id 4740) from its security log. In this particluar example I used users.txt file:

    #Setup arrays
    $SourceEvents = @()

    #Searches for the domain controller with the role of a PDC emulator.
    $PDCServer = (Get-AdDomain).PDCEmulator

    #User list on desktop
    $Users =  Get-Content "c:\users\$env:username\desktop\users.txt"

    #=======================================================================
    #Checking lockout source
    Try{
        $SourceEvents = Foreach ($User in $Users){
            icm -cn $PDCServer {param($User)
                $Object = @{}| select Username,TimeCreated,Source
                $Object.Username = $User

                #Search for first event ID 4740 in security log - source in the ‘Caller Computer Name’ column.
                $Events = Get-WinEvent -FilterHashtable @{LogName="Security";ID="4740"} | Where {$_.message -match $User} | select -first 1
                If($Events){ 
                    $Object.Source = $Events.properties.value[1]
                    $Object.timecreated = $Events.timecreated
                }
                Else{ 
                    $Object.Source = " - "
                    $Object.timecreated = " - "
                }
                $Object
            } -ArgumentList $User -ErrorAction stop | select @{n='ServerName';e={$_.pscomputername}},Username,TimeCreated,Source
        }
    }
    Catch [System.Exception]{
           Write-host "Error" -backgroundcolor red -foregroundcolor yellow
        $_.Exception.Message
    }
    "Checking lockout source on $PDCServer :"
    $SourceEvents | Format-Table -AutoSize -Wrap 
source
source

I wanted to check all of this in single script. After combining both codes you gonna get report for currently locked users and source information.

Final script:

    #Setup arrays
    $LockedUsers = @()
    $SourceEvents = @()

    #Searches for the domain controller with the role of a PDC emulator.
    $PDCServer = (Get-AdDomain).PDCEmulator

    #=======================================================================
    #Checking locked users
    Search-ADAccount -LockedOut | select -first 10 | foreach{
        $City = $Object = $Null
        $City = (Get-ADUser -Identity $_.name -Properties City).City
        $Object = New-Object PSObject -Property ([ordered]@{ 
            Name         = $_.name
            Locked       = $_.lockedout
            Location     = $City
            UPN          = $_.UserPrincipalName        
        })
        $LockedUsers += $Object
    }
    "Currently locked users:"
    $LockedUsers | Format-Table -AutoSize -Wrap
    $Users =  $LockedUsers.Name

    #=======================================================================
    #Checking lockout source
    Try{
        $SourceEvents = Foreach ($User in $Users){
            icm -cn $PDCServer {param($User)
                $Object = @{}| select Username,TimeCreated,Source
                $Object.Username = $User

                #Search for first event ID 4740 in security log - source in the ‘Caller Computer Name’ column.
                $Events = Get-WinEvent -FilterHashtable @{LogName="Security";ID="4740"} | Where {$_.message -match $User} | select -first 1
		        If($Events){ 
                    $Object.Source = $Events.properties.value[1]
                    $Object.timecreated = $Events.timecreated
                }
                Else{ 
                    $Object.Source = " - "
                    $Object.timecreated = " - "
                }
                $Object
            } -ArgumentList $User -ErrorAction stop | select @{n='ServerName';e={$_.pscomputername}},Username,TimeCreated,Source
        }
    }
    Catch [System.Exception]{
	    Write-host "Error" -backgroundcolor red -foregroundcolor yellow
        $_.Exception.Message
    }
    "Lockout source found in $PDCServer :"
    $SourceEvents | Format-Table -AutoSize -Wrap

I hope this was informative for you 🙂 See you in next articiles.
How to create html report for AD Users?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.