Inactive AD user disable review workflow
Two-phase review checklist for identifying inactive AD user accounts, validating inactivity evidence, applying exclusions, capturing approval, and preparing rollback details before any disable action.
Good For
- Quarterly stale account review
- Disable candidate evidence for tickets and CAB review
- AD hygiene reviews with HR or service owner input
- Pre-disable reporting with rollback capture
How to Use It
- Phase 1: Build the candidate list: Define the inactivity threshold in days, commonly 60, 90, or 120, and record it in the ticket. Export a current enabled-user baseline and a separate inactive-user candidate list using LastLogonDate-based evidence. Record the domain queried, date/time of query, operator name, and source DC or management host used. Keep raw CSV output unchanged; create a working copy for annotations.
- Apply exclusions before review: Exclude known service, application, batch, integration, kiosk, shared mailbox-linked, break-glass, and vendor-managed accounts. Check for exclusion signals such as PasswordNeverExpires, ServicePrincipalName presence, privileged group membership, or description text indicating non-human use. Exclude accounts covered by active leave-of-absence, legal hold, or pending termination workflows if your organization requires separate handling. Mark each exclusion with an owner, evidence source, and review date.
- Phase 2: Validate inactivity evidence per account: For each remaining candidate, review LastLogonDate, PasswordLastSet, WhenChanged, manager, department, and description. Confirm whether the account appears in high-risk or business-critical groups and capture group membership evidence. Cross-check with at least one non-AD source where available, such as HR roster, ticket history, VPN usage, email activity, IAM records, or endpoint management. Classify each account as Disable recommended, Hold for owner response, Excluded, or Insufficient evidence.
- Capture approval and planned action: For each Disable recommended account, capture approver name, role, date, and approval channel such as ticket, email, or CAB note. Record the planned disable date, rollback window, and post-disable checks required. Capture rollback essentials before any action: OU, current group membership export, manager, description, and any known dependencies. If owner response is pending, set a review due date and escalation path.
- Produce operator-ready evidence: Create a final review CSV with one row per account and columns for threshold, exclusion reason, evidence sources, decision, approver, and rollback notes. Attach raw baseline CSV, candidate CSV, per-user group exports for high-risk accounts, and operator notes to the ticket or evidence store. Summarize totals: candidates found, excluded, approved to disable, on hold, and unresolved. Ensure the checklist output is complete enough for a separate execution runbook to disable accounts later without re-discovery.
Execution Modes
- ad-filtered
Inputs and Outputs
Inputs
- InactivityThresholdDays
- TargetDomain
- ExclusionCriteria
- AuthoritativeSources
Outputs
- verbose-console
- csv
- operator-notes
Command Starter
Changes system state: review before running
# ---------------------------------------------------------------------
# Read-only candidate review inputs
# ---------------------------------------------------------------------
$DaysInactive = 45
$OutputPath = '.\inactive-user-review-candidates.csv'
# Search-ADAccount is useful for a review starter, but final disable decisions
# should be corroborated with your accepted inactivity evidence standard.
$Candidates = Search-ADAccount -AccountInactive -UsersOnly -TimeSpan (New-TimeSpan -Days $DaysInactive) |
Get-ADUser -Properties Enabled, LastLogonDate, PasswordLastSet, Description
$Results = foreach ($User in $Candidates) {
[pscustomobject]@{
SamAccountName = $User.SamAccountName
Enabled = $User.Enabled
LastLogonDate = $User.LastLogonDate
PasswordLastSet = $User.PasswordLastSet
Description = $User.Description
ReviewDecision = 'PendingOwnerReview'
}
}
# Local evidence file only. No account is disabled by this starter.
$Results | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8
$Results | Format-Table -AutoSizeValidation
- Candidate CSV contains only currently enabled user accounts and excludes disabled objects from the initial list.
- Each Disable recommended record has at least one AD inactivity signal and one corroborating source or documented owner confirmation.
- Each exclusion has a stated reason, named owner or system, and review timestamp.
- Rollback capture exists for every approved account, including current OU and group membership evidence.
Reporting
- Decision summary: total candidates reviewed, excluded, approved to disable, on hold, and unresolved.
- Evidence summary: baseline CSV, candidate CSV, high-risk group membership exports, and corroborating source references attached to the ticket.
- Approval summary: approver, approval date, planned disable date, rollback window, and escalation owner per account or batch.
Safety Notes
- This workflow performs read-only directory queries and writes a local CSV review file. It does not disable accounts.
- Use your approved inactivity evidence standard before moving from a review CSV to an executor runbook.
- Privileged users, service identities, recent password resets, and documented leave-of-absence cases need explicit review before any disablement decision.