Audit Active Directory User Accounts with PowerShell
Use this read-only report to review enabled user accounts in an Active Directory organizational unit (OU), including the replicated last-logon timestamp and password last-set date. It helps identify accounts for owner verification; it does not prove that an account is unused, and it makes no account changes.
Run the report from a system with the Active Directory PowerShell module and read access to the target OU. Replace the example distinguished name with the OU your team is responsible for, and protect the exported file as directory data.
Step 1: Confirm the Module and OU Scope
Load Active Directory Tools and Set the Search Base
PrerequisitesUse an administrative workstation with Remote Server Administration Tools or the Active Directory module already installed. Query a specific OU to keep the review focused and to avoid exporting unrelated directory records.
Import-Module ActiveDirectory$SearchBase = "OU=Employees,DC=contoso,DC=com"$Cutoff = (Get-Date).AddDays(-90)
Get-ADOrganizationalUnit -Identity $SearchBase | Select-Object Name, DistinguishedName❯ View Expected Console Output
Name DistinguishedName---- -----------------Employees OU=Employees,DC=contoso,DC=comStep 2: Collect Enabled User Accounts
Read Account and Logon Metadata
InventoryRetrieve enabled user objects and request the additional properties needed for review. LastLogonDate is based on the replicated lastLogonTimestamp attribute, so it can lag behind a user’s actual most recent logon. Treat older values as review signals, not proof of inactivity.
$Users = Get-ADUser -Filter 'Enabled -eq $true' ` -SearchBase $SearchBase ` -Properties LastLogonDate, PasswordLastSet, Mail
$Users | Select-Object Name, SamAccountName, UserPrincipalName, Mail, Enabled, LastLogonDate, PasswordLastSet | Sort-Object LastLogonDate❯ View Expected Console Output
Name SamAccountName Enabled LastLogonDate PasswordLastSet---- -------------- ------- ------------- ---------------Alex Morgan amorgan True 6/10/2026 9:14:00 AM 5/20/2026 3:02:00 PMStep 3: Flag Records for Owner Review
Create a Review Queue for Older Logons
AnalysisKeep the full inventory, but add a review flag when a last-logon value is missing or older than the chosen cutoff. Service accounts, leave of absence, seasonal work, and replication timing can all explain an old timestamp, so confirm ownership and purpose before taking action.
$Review = $Users | Select-Object Name, SamAccountName, UserPrincipalName, Mail, LastLogonDate, PasswordLastSet, @{Name = 'ReviewReason'; Expression = { if (-not $_.LastLogonDate) { 'No replicated logon timestamp' } elseif ($_.LastLogonDate -lt $Cutoff) { 'LastLogonDate older than cutoff' } else { 'Recent replicated logon timestamp' } }}
$Review | Where-Object ReviewReason -ne 'Recent replicated logon timestamp' | Format-Table -AutoSize❯ View Expected Console Output
Name SamAccountName LastLogonDate ReviewReason---- -------------- ------------- ------------Taylor Reed treed No replicated logon timestampAlex Morgan amorgan 6/10/2026 LastLogonDate older than cutoffStep 4: Export and Review the Report
Save a Dated CSV for the Account Owner
ReportingExport the inventory to a dated CSV and share it only with authorized reviewers. Confirm each flagged account with its owner and service dependencies. If the review leads to a disablement or removal, follow your organization’s separate approval and change process.
$ReportPath = Join-Path $env:TEMP "ad-user-review-$(Get-Date -Format yyyyMMdd).csv"$Review | Export-Csv -Path $ReportPath -NoTypeInformation -Encoding utf8Get-Item $ReportPath | Select-Object FullName, Length, LastWriteTime❯ View Expected Console Output
FullName Length LastWriteTime-------- ------ -------------C:\Users\Admin\AppData\Local\Temp\ad-user-review-20261003.csv 2480 ...See Microsoft’s Get-ADUser reference for filters, properties, and search scope options.