Lock Out Active Directory User Accounts with PowerShell

As I’m sure you’re aware, there’s no setting where you can simply flip a switch to lock out Active Directory user accounts. So what is one to do if you need some locked out accounts to do testing with?

This script is something I whipped up to accomplish just that because I’m working on another blog where I need some locked out Active Directory user accounts to work with. This script requires the RSAT tools to be installed on the workstation that it is being run from, specifically the Active Directory and Group Policy modules.

First, let me say that some assumptions are being made in this script and this is being blogged so I’ll be able to figure out how I accomplished this task the next time I need to do the same thing.

The script first checks to see if a lockout policy is defined in the default domain group policy so that it doesn’t try to lock out accounts if no lockout policy exists. Then it iterates through each account in a specified OU in my test Active Directory environment and tries to run the Invoke-Command cmdlet with that account and an invalid password against one of the servers in my test environment until the user account is locked out and then it moves onto the next account:


There are several reasons why an account may never become locked out which would cause the previous script to become stuck in a runaway loop that would never finish.

Because of this I decided to write another version of this script and I’ve really never had a good reason to use a “For” loop in PowerShell so I decided to work that into it as well. The following script uses the “LockoutBadCount” from the “Default Domain Policy” GPO to know how many times to try the password for each account before it should become locked out, that’s assuming Fine-Grained Password Policies aren’t being used.

You’ll notice that Andrew0’s account wasn’t locked out, that’s because it’s disabled:


The “if” statement portion is the really neat part of the previous script to me because it not only makes sure a “LockoutBadCount” value is defined in the “Default Domain Policy” GPO before attempting to run the code contained inside of the “if” block, but it also assigns the returned numeric value of “LockoutBadCount” (if there is one) to the $LockoutBadCount variable which is used in the “For” loop.

In the following example, the user accounts are first unlocked that were previously locked out, then the number of user accounts that are currently locked out is checked (which is zero), then the number of accounts that exists in the “AdventureWorks Users” OU is determined (there are 290 of them). The amount of time that the lockout script takes to lockout all of those 290 user accounts is determined (it takes a total of 46 seconds to lock out all of them). The number of locked out user accounts in the domain is then checked (the end result is 290 locked out user accounts in the domain):


This is really cool stuff 🙂 and remember this is for testing purposes only.

Disclaimer: “All data and information provided on this site is for informational purposes only. Mike F Robbins (mikefrobbins.com) makes no representations as to accuracy, completeness, currentness, suitability, or validity of any information on this site and will not be liable for any errors, omissions, or delays in this information or any losses, injuries, or damages arising from its display or use. All information is provided on an as-is basis.”



  1. Harry

    This is really cool! Thanks for sharing.

  2. Brady

    As an alternative to brute forcing it, would setting the bitwise lockout flag (0x0010) in the UAC variable lock an account immediately? https://support.microsoft.com/en-us/help/305144/how-to-use-the-useraccountcontrol-flags-to-manipulate-user-account-properties

    • Eric

      That would not work because that value is a combination of all of the attributes for that user account. So for example, doing this in decimal because its easier to explain, if I have a NORMAL_ACCOUNT (512) with DONT_EXPIRE_PASSWORD (65536) enabled the total value for that account is added to get (66048). If you then wanted to lock the account you would have to add 16, but if the account was already locked you would be adding another 16 to get to 32, which would set it to PASSWD_NOTREQD. You don’t want that…. Hope that makes sense.

      • DerekM

        I know this is old but that’s great explanation to problem that doesn’t exist. You would just need to check to see if the account is locked before, adding 16 to the existing userAccountControl value.


Leave a Reply

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

%d bloggers like this: