How to Clean Up Active Directory

Cleaning up the Active Directory

Active Directory (AD) is one of those products that tend to get bloated. The more data you have on hand, the harder it is to do anything, from managing AD users to setting up AD backups. It’s a product where lots of people are making changes every day and ultimately ends up being this enormous pile of stuff that somehow still works. Even the most well-intentioned IT department always seems to end up with an Active Directory environment that’s got lots of user accounts no longer needed, GPOs attached to OUs people didn’t even know existed, and computer accounts that represented computers long gone. This state seems to creep up on people. One day, someone sits down in front of Active Directory Users and Computers (ADUC) and has that moment where they go, “Wow! This needs to be cleaned up.”.

Once someone in your organization has that moment, it’s probably going to be a daunting and overwhelming task. You may start a project to “clean up stuff” but you’ll soon find that right-clicking and deleting isn’t going to cut it. There are lots of ways to make this project a success with the first task being to define what exactly “clean up” means. For this article, we’re going to focus on unused user accounts. More specifically, we’re going to focus on three attributes that a user account might have that would deem it “deletable.” Those attributes are disabled accounts, accounts that haven’t been used in X days, and accounts with expired passwords.

One of the easiest ways to find these potentially unused accounts is to use PowerShell. The ActiveDirectory PowerShell is a module that includes an extremely useful cmdlet called Search-AdAccount that makes building queries and returning exactly what we need easily. Before this cmdlet can be used, however, you must download the Remote Server Administration Tools (RSAT) package from Microsoft. Once RSAT is installed, you should have the ActiveDirectory module, and you’re ready to go! Also, for any of the below code to work, I’m assuming you’re on a Windows PC that’s domain-joined to the same domain as the users you’d like to find. With that being said, let’s get to it!

Find Disabled Accounts in Active Directory

The first task is finding disabled accounts. To find disabled accounts, we’ll use the Search-ADAccount cmdlet. This cmdlet has a single parameter called Disabled which makes this task a cinch. Simply run Search-AdAccount -AccountDisabled and voila, all of your disabled accounts are shown. Notice below that I used the UsersOnly parameter because this cmdlet can also find disabled computer accounts as well.

C:> Search-ADAccount -UsersOnly -AccountDisabled -Server dc

AccountExpirationDate :
DistinguishedName : CN=Guest,CN=Users,DC=mylab,DC=local
Enabled : False
LastLogonDate :
LockedOut : False
Name : Guest
ObjectClass : user
ObjectGUID : 89cfaf2b-c6d8-4ae0-a720-e2da7d201717
PasswordExpired : False
PasswordNeverExpires : True
SamAccountName : Guest
SID : S-1-5-21-4117810001-3432493942-696130396-501
UserPrincipalName :

Find Inactive User Accounts in Active Directory

Another usual suspect to clean up is inactive user accounts which are a little harder to track down. “Inactive” is a subjective term so for our purposes we’re going to define “inactive” as any user as having a value of LastLogonTimeStemp older than 30 days. You’ll find lots of articles on the Internet about finding inactive users but some people don’t realize that it’s much easier than building complicated AD LDAP filters. The support is native in Search-AdAccount.

We can use  Search-AdAccount -AccountInactive -UsersOnly -Timespan 30.00:00:00 to immediately find all AD user accounts that haven’t been used in 30 days.

There is one caveat though. Microsoft only updates the LastLogonTimestamp attribute, which is the same as LastLogonDate, once every 14 days to prevent replication storms. Because of this characteristic of AD, using this method (or even Get-AdUser or Get-AdComputer with the advanced filter) won’t be 100% accurate if you’re attempting to get accounts with inactivity older than 14 days. So be forewarned.

Finally, we need to find all AD users that have an expired password that are no longer needed. This one is tricky because “active” user accounts could have an expired password if it just recently expired. I not only need to find expired passwords but also how long ago they expired. If they expired, say, 30 days or longer ago I can assume that these user accounts are, in fact, inactive.

To find how long ago a password expired, I first have to find the maximum password age for the domain’s password policy. I can do this with the Get-AdDefaultDomainPasswordPolicy cmdlet.

$MaxPasswordAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge.Days

Next, I can find all user accounts that have an expired password then filter those users’ accounts by seeing the last time their password was last set and ensuring that was before the maximum time the password could be plus 30 (how old I’m defining the account to be).

The code will look something like this:

Search-AdAccount -PasswordExpired -UsersOnly | Where-Object {((Get-Date) - (Get-AdUser -Filter "samAccountName -eq $_.SamAccountName").PasswordLastSet) -lt ($MaxPasswordAge + 30)}

The next time you’re searching AD for inactive records, be sure to look at Search-AdAccount to see if it already does what you’re trying to do. It might just save you a ton of time!

Adam Bertram is a Microsoft Windows Cloud and Datacenter Management MVP and has authored various training courses, is a regular contributor to numerous print and online publications and presents at various user groups and conferences. You can find Adam at

Adam Bertram photo

Next Steps

Building an efficient and effective IT team requires a centralized solution that acts as your core service deliver tool. NinjaOne enables IT teams to monitor, manage, secure, and support all their devices, wherever they are, without the need for complex on-premises infrastructure.

Learn more about Ninja Endpoint Management, check out a live tour, or start your free trial of the NinjaOne platform.

You might also like

Ready to become an IT Ninja?

Learn how NinjaOne can help you simplify IT operations.

Watch Demo×

See NinjaOne in action!

By submitting this form, I accept NinjaOne's privacy policy.

Start a Free Trial of the
#1 Endpoint Management Software on G2

No credit card required, full access to all features

NinjaOne Terms & Conditions

By clicking the “I Accept” button below, you indicate your acceptance of the following legal terms as well as our Terms of Use:

  • Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms.
  • Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party.
  • Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library belonging to or under the control of any other software provider.
  • Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations.
  • Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks.
  • Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script.
  • EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).