Archives
- April 2018
- March 2018
- August 2017
- June 2017
- May 2017
- April 2017
- March 2017
- February 2017
- January 2017
- December 2016
- November 2016
- October 2016
- September 2016
- June 2016
- May 2016
- August 2015
- June 2015
- February 2015
- November 2014
- September 2014
- April 2014
- February 2014
- December 2013
- September 2013
- June 2013
- April 2013
- November 2012
- August 2012
- July 2012
- April 2012
- March 2012
- January 2012
- November 2011
- October 2011
- August 2011
- April 2011
- March 2011
- February 2011
- December 2010
Categories
- $Profile
- Active Directory
- Annoyances
- Application Compatibility
- Authentication
- Building Labs
- Console
- DHCP
- Essentials
- Exchange
- Group Policy
- Hardware
- Hyper-V
- IT Admin
- Kindle
- MultiPoint
- net commands
- Network Administration
- Networking
- Patching
- PowerShell
- PowerShell Functions
- PSCredential
- RD Session Host
- RDSH
- Registry
- Remote Desktop
- RemoteApp
- RemoteFX
- SBS
- Security
- Survival Guide
- Uncategorized
- Windows 10
- Windows Azure
- Windows Backup
- Windows Server
- Windows Server 2016
- Windows Server Core
- Windows Update
- WMF
- WMI
- WMS
To find out more, including how to control cookies, see here: Cookie Policy
Active Directory — Unlocking a User Account with PowerShell

As any SysAdmin knows, users periodically lock themselves out of their accounts, usually because they forgot a password or somehow mistyped it too many times. And after all, if it failed once, why not keep trying it? Unlocking that account is NOT something you do with Set-ADUser, unfortunately, because the PowerShell ActiveDirectory module has a special, single-purpose cmdlet - Unlock-ADAccount. Now, it doesn't take a whole script to run a single cmdlet, but sometimes there are good reasons to wrap a command in a more complicated script, and this is one I've had to. Primarily because I work on at least three different domains that are unrelated - my home domain, my "work" domain, and my testlab domain. With this script, I can also take advantage of an encrypted password for one of those domains, stored securely on my main desktop's hard disk. Plus, I've added in a bit of code to go grab the current holder of the FSMO PDCEmulator role, since I'd prefer to unlock the account directly against that PDC.
Also, to make life easier, and allow us to stick this in the middle of a pipeline when we need to, we'll add the ability to handle parameters from the pipeline. We do that in the Param section:
[CmdletBinding()] Param( [Parameter(Mandatory=$True,ValueFromPipeline=$true,Position=0)] [alias("user","account")] [string[]] $Identity, [Parameter(Mandatory=$False,ValueFromPipeline=$True,Position=1)] [string] $Domain = "DOMAIN", [Parameter(Mandatory=$False,ValueFromPipeline=$True)] [PSCredential] $Credential = $NULL )
You'll notice here that we've allowed for each of our parameters to accept pipeline input. And they'll accept that "ByValue", meaning that the piped objects must have the same .NET type, or must be able to be converted to that type. So only an actual PSCredential object can be accepted for the -Credential parameter.
Next, we want to be able to handle credentials in any of several ways. So we use:
if ( $Credential ) { $myCred = $Credential } else { # Test if there is a stored, encrypted, password we can use $pwPath = "$home\Documents\WindowsPowerShell\$domainPW.txt" if (Test-Path $pwPath ) { $mypw = Get-Content $pwPath | ConvertTo-SecureString $myCred = New-Object -TypeName System.Management.Automation.PSCredential ` -ArgumentList "$DOMAIN\Charlie",$mypw } else { # Prompt for a credential, since we don't seem to have one here. $myCred = Get-Credential } }
Let's look at this for a moment. First, we know from the Param section that the default value of $Credential is $NULL, so our first test is whether that's been overridden at the command line with either a pipelined parameter, or a specifically entered credential object. If so, we're good, and we use that. But failing that, we'll check if there's one stored securely on disk. (More on storing credentials on disks in another post soon.) If we've stored one on disk that matches the domain we're going against, we'll use that. If not, and we still don't have a PSCredential object we can use, we'll simply prompt for one.
Next up, we want to run this against the domain controller that hosts the PDCEmulator role. Not a big deal in simplified domain environment, but really a good idea in a complicated, multi-site environment where site-to-site propagation is a bit slow.
$PDC = (Get-ADDomain -Identity $DOMAIN -Credential $myCred).PDCEmulator
We'll plug the value of $PDC into the -Server parameter of our AD commands.
Finally, the meat of the whole thing. I'm not assuming you're only unlocking a single account, so I've designed this to take a list of strings ([string[]]). (A list can, of course, be a list of length one.)
foreach ($usr in $Identity) { Unlock-ADAccount -Identity $usr ` -Credential $myCred ` -Server $PDC ` -PassThru ` | Get-ADUser -Properties LockedOut
That last line ensures that we report back in a way that shows the account no longer locked out. But for Get-ADUser to actually do anything, you need to include the -PassThru parameter in the Unlock-ADAccount command. Otherwise, nothing at all gets passed to the Get-ADUser command.
So, here's the whole thing:
<# .Synopsis Unlocks a domain account .Description Unlock-myUser accepts an array of DOMAIN account names and unlocks the accounts This script accepts pipeline input for the credential. If no credential is supplied, it will attempt to use one you have stored on disk. Failing that, it will prompt you for credentials. .Example Unlock-myUser -Identity Charlie Unlocks the account of Charlie .Example Unlock-myUser -Identity Charlie, Sharon Unlocks the accounts of Charlie and Sharon .Example Unlock-myUser -Identity Charlie -Domain TREYRESEARCH ` -Credential (Get-Credential ` -username "TREYRESEARCH\Alfie" ` -Message "Enter your Domain PW") Unlocks the account of TreyResearch\Charlie, prompting Alfie for credentials. .Parameter Identity The AD identity of the user or users whose acounts are to be reset. .Parameter Domain The Active Directory domain of the user or users whose accounts are to be reset .Parameter Credential The user credentials to run the script under. .Inputs [string[]] [string] [PSCredential] .Notes Author: Charlie Russel Copyright: 2016 by Charlie Russel : Permission to use is granted but attribution is appreciated Initial: 07 Sept, 2016 (cpr) ModHist: 09 Sept, 2016 (cpr) - added PDC test and Domain parameter : #> [CmdletBinding()] Param( [Parameter(Mandatory=$True,ValueFromPipeline=$true,Position=0)] [alias("user","account")] [string[]] $Identity, [Parameter(Mandatory=$False,ValueFromPipeline=$True,Position=1)] [string] $Domain = "DOMAIN", [Parameter(Mandatory=$False,ValueFromPipeline=$True)] [PSCredential] $Credential = $NULL ) if ( $Credential ) { $myCred = $Credential } else { # Test if there is a stored, encrypted, password we can use $pwPath = "$home\Documents\WindowsPowerShell\$domainPW.txt" if (Test-Path $pwPath ) { $mypw = Get-Content $pwPath | ConvertTo-SecureString $myCred = New-Object -TypeName System.Management.Automation.PSCredential ` -ArgumentList "DOMAIN\Charlie",$mypw } else { # Prompt for a credential, since we don't seem to have one here. $myCred = Get-Credential } } # Find out which server holds the PDC role. # Useful in complicated, multi-site environments where # Domain changes might not propagate quickly. $PDC = (Get-ADDomain -Identity $DOMAIN -Credential $myCred).PDCEmulator foreach ($usr in $Identity) { Unlock-ADAccount -Identity $usr ` -Credential $myCred ` -Server $PDC ` -PassThru ` | Get-ADUser -Properties LockedOut }
As always, feel free to use this script or any portion of it that you find useful. However, if you do, I'd appreciate attribution and a pointer back to my blog.


Leave a Reply