I just started a contract to clean up an Active Directory system for a large company. I was told it would be quite the busy work but after reviewing the system and seeing how disorganized and messy it is, I realized that I will not be able to perform my duties to their fullest. Essentially this company has far too many accounts that are not active but cannot be deleted just yet. I want to perform a "Scream Test" for certain accounts and delete later. If this was only a few thousand inactive accounts it would be one story but unfortunately it is quite a few thousand (I haven't taken an exact number yet but it is over 20,000). I was curious if anyone knew of a way to sort through this information in an automated fashion other than using Hyena to get reports and then going through them one by one.

  • 2
    (I haven't taken an exact number yet but it is over 20,000) This what we professionals refer to as a "red flag." If it's not too late, run away. Don't walk, run. If it is too late to do that, tell them you'll need more money. A lot more money. If they come through with the lot more money, it's not too difficult to punch up a PowerShell script that can disable accounts (and maybe move them, if you want) based on AD attributes like last logon time. Make sure your E&O insurance is current, but most importantly, run away from this one. Sounds like they new a new AD, not a cleanup. – HopelessN00b Apr 15 '14 at 21:17
  • 2
    I don't want to run away. I've been in IT for about 6 years now but this is the first step away from Help Desk/Service Desk/Desktop Support I've had and I figure its a great way to crash into it lol. I'm getting paid pretty decently compared to what I have been paid before. Where would I begin to learn these scripts? MSDN's documentation is atrocious. – Thatsnotamuffin Apr 15 '14 at 21:23
  • 2
    I don't want to run away. You really do... but I guess everyone has to learn somethings the hard way. At least make sure you're covered with Errors and Omissions insurance, especially as your first romp away from the Helpdesk is the mother of all minefields. As to where you learn these scripts... O'Reilly books. Google's helpful. Technet's Scripting Guy Blog might be another starting place. It has a relatively topical post here that you could adapt. – HopelessN00b Apr 15 '14 at 21:29
  • 4
    Make sure you rigorously follow their change-control policy, assuming they have one. If they don't, get documented proof that you have approval from whoever signs/authorizes the checks before you perform anything. Also, -whatif is now your best friend, hopefully with benefits. – mfinni Apr 15 '14 at 21:39
  • 7
    Sometimes bad experiences lead to good experience. Caution is warranted but this may give you deeper insight, knowledge and experience. Make sure you've mapped out and documented (and have approval for) your boundaries on this project, client expectations, limitations, what the desired end goal is, etc. – joeqwerty Apr 15 '14 at 23:05

I'll presume your question lies in finding inactive accounts.

I use JoeWare's Oldcmp tool. http://www.joeware.net/freetools/tools/oldcmp/index.htm still after all these years.

It can find inactive AD accounts by looking at password age and specifically LLTS = lastLogonTimestamp

It's simple enough to at least get you started and easier than powershell. Then disable those accounts and use ADUC to create a custom query window for disabled accounts. That way you don't have to move anything that might need re-enabled later.

BUT...I agree with Hopeless and Mfinni, and would say you better clearly lay out what you plan on doing with management BEFORE implementing anything.


I use Powershell to do so, calling the lastlogondate propertie.

Here i return all samaccountname that have a last logon date older than 30 days (from today) :

$datenow = Get-date
$users=Get-ADuser -Filter * -properties samaccountname,lastlogondate
foreach($user in $users) {
  $lastlogon = $user.lastlogondate
  if($lastlogon -lt $treshold) { 
    echo $user.samaccountname
    echo $user.lastlogondate
    echo "------------------------------------------------"

From here, you can :

  • Adjust the date treshold to your needs
  • Disable the AD Account (Disable-ADAccount)
  • Whatever else you want (at least, most of things)
  • Isn't the attribute 'lastlogontimestamp'? – uSlackr Apr 16 '14 at 11:42
  • 1
    It's just LastLogon and it's unsuited for this purpose as it is not replicated. LastLogonTimestamp is a great alternative, but a bit tricky to figure out! – Mathias R. Jessen Apr 16 '14 at 15:08
  • I do have one question. I'm fairly new to powershell but I seem to be picking it up fairly quickly. How can I go about specifying a more specific subset of user. For example: There are 30 some thousand users in the USER OU. However they are broken down into separate groups and I want to split the work up a bit and work through each group one by one. So if I wanted to specify a different OU in the USER OU where and what would I put in the script? – Thatsnotamuffin Apr 16 '14 at 15:22
  • Why would you do this : "split the work up a bit"? I don't understand what you're trying to do, or why you're trying to do it. – mfinni Apr 16 '14 at 19:14
  • 1
    @MathiasR.Jessen actually, the Powershell AD objects do expose the LastLogonDate property - it basically is the DateTime representation of the date part of .LastLogonTimestamp. You even can use the property as a -Filter in Get-ADUser like $date=((Get-Date).AddDays(-30)); Get-ADuser -Filter { LastLogonDate -lt $date } -properties samaccountname,lastlogondate – the-wabbit Apr 17 '14 at 13:30

Good advice above re: change control and documenting permissions. I would try an approach like this

Build an inventory of account that includes attribute like lastLogonTimestamp, pwdLastSet, whencreated and whenchanged. You can grab all of this with Powershell and get-ADUser. I'm sure lots of script exist around the web - the TechNet Script repository is a good place to start

Use the inventory to locate target accounts.

Before you make an changed to AD, consider testing everything in a test environment. There are some scripts in the repository that will allow you to make a copy of AD (OUs, Users & groups) into your test environment.


I did a simliar task a few years back, though on a much smaller scale than you're facing. The first thing we did was to implement ManageEngine's AD Audit product in order to get a handle on accounts. We probably let this run for a few weeks in order to generate metrics before we did anything further. From there, we were able to track down where account logins were coming from, and we were able to deal with them in a controlled fashion.

AD Audit is a fairly low-cost product and the excel reports are quite good so we were very happy with our decision to go with it.


Here are some solutions below. Not too sure if it's what you are looking for.

Example #1: This will search the OU Users in the domain domain.local using the date specified. You can change these below and output the Username and LastLogonTimestamp like:





Import-Module Active Directory
$lastdate = "09 April 2014 23:59:59"
$users = Get-ADUser -Filter * -SearchBase "ou=users,dc=domain,dc=local" -ResultPageSize 0 -Prop CN,lastLogonTimestamp | Select     CN,@{N='lastlogontimestamp'; E={[DateTime]::FromFileTime($_.lastlogontimestamp)}}
foreach ($user in $users) {
if ($user.lastlogontimestamp -lt $lastdate) {
echo $user.CN
echo $user.lastlogontimestamp.tostring('d/M/yyyy')

Example #2: This will search the OU Users in the domain domain.local. Then Export it to a CSV then you can see your data a bit better.

Import-Module ActiveDirectory
Get-ADUser -Filter * -SearchBase "ou=users,dc=domain,dc=local" -ResultPageSize 0 -Prop CN,lastLogonTimestamp | Select    CN,@{N='lastLogonTimestamp'; E={[DateTime]::FromFileTime($_.lastLogonTimestamp)}} | Export- CSV -NoType .\last.csv

With Example 2 you could draw up a list of users you are going to remove/disable in CSV / Excel and go to the Management with these.

Hope this helps!


As many others have mentioned TEST before making any changes, especially when scripting or making production changes in AD.

I would look into the free Active Directory module (it's actually a Snap-in) from Quest

The Quest cmdlet Get-QADUser includes various acocount-inactivity related paratmers such as -Inactive,-InactiveFor,-ExpiredFor,-NotLoggedOnFor and -PasswordNotChangedFor that allow you to easily report inactive accounts based on values supplied to these parameters. I suggest downloading the module and using Get-Help Get-QADUser -Full | more or if you have the ISE installed, I prefer Get-Help Get-QADUser -Show to get all the details in a separate window.

An example could be:

Get-QADUser -ExpiredFor 30 -NotLoggedOnFor 30 -PasswordNotChangedFor 90 | Select-Object Name,SamAccountName,PasswordLastSet,PasswordIsExpired,LastLogonTimestamp,AccountIsExpired | Sort-Object Name | Export-CSV C:\InactiveADUsers.csv -NoTypeInformation -Force

You can get very similar output using the native AD module with a bit more elbow grease.

  • I'm curious as to where to get the Quest tools. I am trying to use the Quest tools in a powershell.ise like environment but it doesn't seem to be working. – Thatsnotamuffin Apr 18 '14 at 16:00
  • @TheNoobofNoobs There is a link to Quest PowerShell Snap-in via the link in my post. After installation, they should be available in the ISE. You can check availability by running Get-Module -List in either a PowerShell window, or within the ISE. The native Active Directory module is part of RSAT (Remote Server Admin Tools) and must be added, manually, after installing the RSATs. – vN3rd Apr 18 '14 at 22:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.