Finding and reporting Active Directory inactive accounts

An Active Directory environment cannot live without the stale accounts. While Active Directory can hold millions of active and inactive objects, that doesn’t necessarily mean that you don’t want to have a process in place that would help you identify the inactive (stale) accounts. In this article, we will help you understand the challenges and how to collect stale user and computer accounts from your Active Directory environment by using PowerShell scripts.

Stale accounts in your Active Directory

Every Active Directory will have stale accounts. Let’s take a look at some of the main reasons that lead to stale accounts in an Active Directory environment.

  • When a computer is renamed and if the AD domain controller is not reachable to delete the previous computer account in the Active Directory database, the old computer account will remain in the AD database. If rename operations happen quite frequently, this will result in hundreds of stale computer accounts.
  • You will have stale user and computer accounts if you migrated your environment and did not remove old computer and user accounts.
  • Whenever an employee leaves an organization, his or her user account will remain in Active Directory unless you have a process that takes care of moving or deleting the account from the Active Directory database.

How to collect stale accounts using PowerShell

Microsoft provides the necessary PowerShell cmdlets that you can use to collect stale accounts information from Active Directory easily. You can use Get-ADComputer and Search-ADAccount PowerShell cmdlets to collect stale accounts.

Script 1: Collecting stale computer accounts

You can use the PowerShell script below to collect stale computer accounts from each domain in an Active Directory forest. Please make sure to modify the Active Directory forest name in $CurForestName variable in the script. The script generates a CSV report under C:\Temp\StaleCompAccounts.CSV file. The script will collect computer name, SamAccountName, DistinguishedName, and OperatingSystem version.

### Script Starts Here ###

$GDomList = "C:\Temp\DomList.DPC"
Remove-item $GDomList -ErrorAction SilentlyContinue
$TestCSVFile = "C:\Temp\StaleCompAccounts.CSV"
Remove-item $TestCSVFile -ErrorAction SilentlyContinue
$ThisString="Computer Name, SamAccountName, DistinguishedName, OperatingSystem, In AD Domain"
Add-Content "$TestCSVFile" $ThisString
$CurForestName = "TechGenix.com"
$R=Get-ADForest $CurForestName
ForEach ($DomName in $R.Domains)
{
Add-Content $GDomList $DomName
}
$TotNo=0
$ItemCount=0
$TestText = ""
$TestStatus=""
$SumVal = ""
$DaysInactive = 90
$time = (Get-Date).Adddays(-($DaysInactive))
ForEach ($ThisDomain in Get-Content "$GDomList")
{
$CompsInactiveCount=Get-ADComputer -Filter {LastLogonTimeStamp -lt $time} -ResultPageSize 2000 -resultSetSize $null -Server $ThisDomain -Properties Name,OperatingSystem,SamAccountName,DistinguishedName
IF ($Error.count -eq 0)
{
}
else
{
$ErrorOrNot="Yes"
}
IF ($ErrorOrNot -eq "Yes")
{
$TestText = "Please check to make sure a Domain Controller is reachable to execute AD Test."
$SumVal = ""
$TestStatus="Error executing Dynamic Pack."
}
else
{
$Items = $CompsInactiveCount
$ItemCount=$CompsInactiveCount.Count
$FinalText = ""
$SumVal=$ItemCount
ForEach ($ThisItem in $Items)
{
$TotNo++
}
$FinalVal="Total Stale Computers: ["+$TotNo+"]"+",,,,"+$ThisDomain
Add-Content "$TestCSVFile" $FinalVal
$TotSrv=0
ForEach ($ThisItem in $Items)
{
IF ($ThisItem.OperatingSystem -like "*Server*")
{
$TotSrv++
}
}
$FinalVal="Total Stale Servers: ["+$TotSrv+"]"+",,,,"+$ThisDomain
Add-Content "$TestCSVFile" $FinalVal
ForEach ($ThisItem in $Items)
{
$FinalVal=$ThisItem.Name+","+$ThisItem.SamAccountName+","+'"'+$ThisItem.DistinguishedName+'"'+","+$ThisItem.OperatingSystem+","+$ThisDomain
Add-Content "$TestCSVFile" $FinalVal
}
IF ($TotNo -ge 500)
{
$TestText = "More than 500 Stale computer accounts were found in AD Domains. Please load and check result."
$TestStatus="High"
$SumVal = $TotNo
}
else
{
$TestText = "Less than 500 Stale computer accounts were found in AD Domains. Please load and check result."
$TestStatus="Low"
$SumVal = $TotNo
}
IF ($TotNo -eq 0)
{
$TestText = "No Stale computers were found in Active Directory forest."
$TestStatus="Passed"
$SumVal = $TotNo
}
}
}
$STR = $ADTestName +","+$TestStartTime+","+$TestStatus+","+$SumVal +","+$TestText

### Script Ends Here ###

Script 2: Collecting stale user accounts

You can use the PowerShell script below to collect stale user accounts from each domain in an Active Directory forest. Please make sure to modify the Active Directory forest name in $CurForestName variable in below script. Script generates a CSV report under C:\Temp\StaleUserAccounts.CSV file. The script will collect user name, SamAccountName, and DistinguishedName of stale user accounts.

### Script Starts Here ###

$GDomList = "C:\Temp\DomList.DPC"
Remove-item $GDomList -ErrorAction SilentlyContinue
$TestCSVFile = "C:\Temp\StaleUserAccounts.CSV"
Remove-item $TestCSVFile -ErrorAction SilentlyContinue
$ThisString="User Name, SamAccountName, DistinguishedName, In AD Domain"
Add-Content "$TestCSVFile" $ThisString
$CurForestName = "TechGenix.com"
$R=Get-ADForest $CurForestName
ForEach ($DomName in $R.Domains)
{
Add-Content $GDomList $DomName
}
$TotNo=0
$ItemCount=0
$TestText = ""
$TestStatus=""
$SumVal = ""
ForEach ($ThisDomain in Get-Content "$GDomList")
{
$UsersInactiveAccountList=Search-ADAccount -Server $ThisDomain -AccountInactive -TimeSpan 90.00:00:00 -ResultPageSize 2000 -resultSetSize $null | ?{$_.enabled -eq $true} | Select-Object Name, SamAccountName, DistinguishedName
IF ($Error.count -eq 0)
{
}
else
{
$ErrorOrNot="Yes"
}
IF ($ErrorOrNot -eq "Yes")
{
$TestText = "Please check to make sure a Domain Controller is reachable to execute Dynamic Pack."
$SumVal = ""
$TestStatus="Error executing Dynamic Pack."
}
else
{
$Items = $UsersInactiveAccountList
$ItemCount=$UsersInactiveAccountList.Count
$FinalText = ""
$SumVal=$ItemCount
ForEach ($ThisItem in $Items)
{
$TotNo++
}
$FinalVal="Total Stale User Accounts: ["+$TotNo+"]"+",,,"+$ThisDomain
Add-Content "$TestCSVFile" $FinalVal
ForEach ($ThisItem in $Items)
{
$FinalVal=$ThisItem.Name+","+$ThisItem.SamAccountName+","+'"'+$ThisItem.DistinguishedName+'"'+","+$ThisDomain
Add-Content "$TestCSVFile" $FinalVal
}
IF ($TotNo -ge 500)
{
$TestText = "More than 500 Stale user accounts were found in AD Domains. Please load and check result."
$TestStatus="High"
$SumVal = $TotNo
}
else
{
$TestText = "Less than 500 Stale user accounts were found in AD Domains. Please load and check result."
$TestStatus="Low"
$SumVal = $TotNo
}
IF ($TotNo -eq 0)
{
$TestText = "No Stale user accounts were found in AD Domains."
$TestStatus="Passed"
$SumVal = $TotNo
}
}
}
$STR = $ADTestName +","+$TestStartTime+","+$TestStatus+","+$SumVal +","+$TestText

### Script Ends Here ###

Both PowerShell scripts are part of Dynamic Packs that ship with Active Directory Health Profiler. If you are using Active Directory Health Profiler, create a Health Profile, select an Active Directory forest, add both “Domain Computers Stale Accounts Test” and “Domain Users Stale Accounts Test” Dynamic Packs to the health profile and then execute the health profile. Active Directory Health Profiler will collect the required information and generate a report.

Note that by using the above PowerShell scripts, you can collect stale accounts and have the report generated in a CSV file, but every time you need to collect a list of stale accounts, you will be required to run the scripts manually. It is also worth mentioning that the scripts do not take any action if they find stale accounts such as moving stale accounts to an organizational unit, deleting stale accounts, etc. There are many tools available that can help you collect the information automatically and have the report generated with much more details and then have the reports sent to you via email. One of the products that I have come across is Netwrix Auditor for Active Directory. Netwrix Auditor for AD delivers security analytics about what’s going on in Active Directory and Group Policy. Use this data to mitigate the risk of privilege abuse, prove IT compliance, and streamline troubleshooting.

About The Author

1 thought on “Finding and reporting Active Directory inactive accounts”

  1. Hi Nirmal, great article.

    I´ve a question. What happens with a pc when you leave it powered off for a while? Is it deleted from Active Directory? You have to recreate user profiles?

    Thanks for your reply.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Scroll to Top