How to Find Stale Active Directory User Accounts

Adam Bertram

Adam Bertram

Read more posts by this author.

As an Active Directory admin, there inevitably comes a time where you’ve got dozens or even hundreds of stale user accounts. In my environment of a little over 10,000 user accounts, there’s always a few hundred that are no longer needed at any point in time.

Eventually, someone’s going to be bothered enough of seeing all these unused accounts that they’ll need to be removed. When this happens, I sure hope you’ve got your PowerShell hat on!

Define “Stale”

The first task you’ll have to go through is actually defining what “stale” means. I find that the difficulty of solving a problem in IT isn’t the technical part; it’s the people part. No one ever agrees on what to actually accomplish. Once that’s defined, actually doing it is fairly easy! To find these unused accounts, you’ve got a few different criteria you can key off of:

  • Enabled – If the account is disabled, it’s not being used.
  • PasswordExpired – If the password is expired, it’s not being used
  • PasswordLastSet – If the password hasn’t been set in a long time, it’s stale
  • LastLogonDate – If the account hasn’t even been used, it’s stale

Let’s put these object properties to good use. Notice I don’t use the Filter parameter. Technically, it’s more efficient to put everything you can in this area. It’s always better to filter to the left of the pipe instead of dumping everything out and then filtering from that. This decision was to forego efficiency for code simplicity.

Sometimes performance really isn’t a key factor for me. In this instance, I’m using Where-Object simply because I don’t have to worry about the specific AD provider filter syntax that’s required. I can simply use the same syntax I’m used to with Where-Object.

$MaxAge = 180

Get-AdUser -Filter * -Properties PasswordLastSet,LastLogonDate | Where-Object { 
     $_.PasswordLastSet -lt [DateTime]::Now.Subtract([TimeSpan]::FromDays($MaxAge)) -or 
     $_.LastLogonDate -lt [DateTime]::Now.Subtract([TimeSpan]::FromDays($MaxAge)) -or
     $_.Enabled -eq $false -or
     $_.PasswordExpired -eq $true

This code will get you all of the user accounts that are either disabled, have their password expired, have a passwordlastset older than 6 months or have a lastlogondate older 6 months. This will only show you the user accounts. You could always take it to another level by actually getting brave and piping this to Remove-AdComputer!

Subscribe to Adam the Automator

Get the latest posts delivered right to your inbox

Looks like you're offline!