Skip to content

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

01

Load Active Directory Tools and Set the Search Base

Prerequisites

Use 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.

Terminal window
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=com

Step 2: Collect Enabled User Accounts

02

Read Account and Logon Metadata

Inventory

Retrieve 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.

Terminal window
$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 PM

Step 3: Flag Records for Owner Review

03

Create a Review Queue for Older Logons

Analysis

Keep 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.

Terminal window
$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 timestamp
Alex Morgan amorgan 6/10/2026 LastLogonDate older than cutoff

Step 4: Export and Review the Report

04

Save a Dated CSV for the Account Owner

Reporting

Export 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.

Terminal window
$ReportPath = Join-Path $env:TEMP "ad-user-review-$(Get-Date -Format yyyyMMdd).csv"
$Review | Export-Csv -Path $ReportPath -NoTypeInformation -Encoding utf8
Get-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.

Comments