Monday, October 26, 2015

Using Powershell to unlock Active Directory account Unlock-ADAccount

OK, this is an easy one. There is a command in the ActiveDirectory module that already takes care of this.

Unlock-ADAccount kevmar 

So quick to type and it works so well. But unlocking the account is only part of the issue. The real question is why is it locked. If your lucky, the user will say they just miss-typed it a few times and you can let it go. Sometimes you find an account that just locks over and over. Here is a simple command that works really well in my environment to find the source of the issue:

function Get-ADAccountLockInfo
{
    [cmdletbinding()]
    param(
        $ComputerName = "servername",
        [pscredential] $Credential
    )
   
    $WinEvent = @{
        ComputerName = $ComputerName
        FilterHashtable = @{logname='security';id=4740}
    }
   
    if($Credential)
    {
        $WinEvent.Credential = $Credential
    }
   
    Get-WinEvent @WinEvent | %{
        [pscustomobject]@{
            TimeCreated  = $_.timecreated;
            Username     = $_.properties[0].value;
            ComputerName = $_.properties[1].value
        }
    }
}


Replace the server name with the name of the domain controller that is the PDC emulator. If you do not know what one that is, you can run this once for each domain controller. What it does is queries the security log for event id 4740. It then tells you who is locked at what time and where the source is.

I added a credentials option because I often execute this cross domain. The $WinEvent is a hashtable that I splat to the Get-WinEvent. That makes it easy for me to add the credential to the hashtable when if it is defined.

Any idea how to troubleshoot this with out knowing the event ID to look for? You start with the cell phone and clear any WiFi settings and emails settings. Then do the same for any tablets they have (even at home). Then exit lync and outlook on their laptop and desktop. Open 'Credential Manager' and delete all the saved credentials (do a start menu search for it). Then check all desktops and servers where they may have used RDP to connect to a session but just disconnected when they are done. Then check for services, jobs, tasks, and reporting services connections that may be using that credential.

Yeh, searching the security log is much easier.

1 comment:

Ryan said...

I have something fairly similar, I wont post it all because there are some environment specific things in it.

I use something like this to get it on the PDC emulator:
Invoke-Command -ComputerName (Get-ADDomain | Select -Property PDCEmulator).PDCEmulator{}

The sec log on this server rolls quickly, so have too look in archives (the main reason I use invoke):
$SecLogs += (Get-ChildItem("c:\Windows\System32\Winevt\Logs\") | where{($_.Name -like "Security.evtx") -or ($_.Name -like "Archive-Security*.evtx")}
I also include other locations logs get shipped off to

For each of those pull the events
$WinEvents = Get-WinEvent -Path $SecLog.FullName -FilterXPath '*/System[(EventID=4740)]'

Then for each of those slap the same things in an object for output

The reason for using xpath rather than a hash is you can get in depth, like this:
-FilterXpath '*[System[EventID=4740] and EventData[Data[@Name="TargetUserName"]="username"]]'

or you can use timestamps, etc.

this is a pretty good starting point on xpath
http://www.powershellish.com/blog/2014-12-09-get-winevent-filterxpath