Combined Active Directory maintenance scripts for automated cleanup of disabled computers and groups, plus domain-wide stale server reporting.
| Feature | Description |
|---|---|
| Computer cleanup | Deletes disabled computers from the Disabled OU after 90 days. Stamps the original OU in the info attribute. |
| User cleanup | Deletes disabled users from the Disabled OU after 90 days. Reports enabled users in the OU as anomalies. |
| Group cleanup | Deletes empty groups from the Disabled OU after 90 days. Groups with members are kept and flagged. |
| Stale server scan | Scans the entire domain for enabled servers with no logon in 90+ days. |
| Source OU tracking | Records which OU each object came from before it was moved to Disabled. |
| Summary email | Sends an HTML summary email (computers, users, groups, stale servers) on a configurable day of the week. |
| Script | Purpose | Schedule |
|---|---|---|
Collect-Inventory.ps1 |
Snapshots all computers, users, and groups (plus OUs) to JSON files for change tracking. | Every 6 hours |
Remove-StaleDisabled.ps1 |
Main cleanup -- deletes stale objects, stamps attributes, scans for stale servers, sends email. | Daily at 03:00 |
Install-ScheduledTask.ps1 |
Registers both scheduled tasks (run once as admin). | Manual |
Save-SmtpCredential.ps1 |
Saves encrypted SMTP credentials for the email feature. | Manual |
-
Copy all scripts to a folder on the domain controller (e.g.
C:\Scripts\AD-Maintenance). -
Edit the configuration sections at the top of each script:
Collect-Inventory.ps1-- set$DisabledOU(or leave blank for auto-detection of an OU named "Disabled").Remove-StaleDisabled.ps1-- set$DisabledOU,$RetentionDays,$StaleDays, the SMTP settings ($SmtpServer,$SmtpPort,$SmtpUseSsl), email addresses ($EmailFrom,$EmailTo), and$EmailDay(day of week to send the summary).Install-ScheduledTask.ps1-- set$ScriptDirto match the folder path (and optionally$TaskFolder, the Task Scheduler folder).
-
Save SMTP credentials (as the SYSTEM account):
psexec -s -i powershell -File "C:\Scripts\AD-Maintenance\Save-SmtpCredential.ps1"
-
Register the scheduled tasks (as administrator):
.\Install-ScheduledTask.ps1 -
Run an initial inventory snapshot:
.\Collect-Inventory.ps1 -
Test the cleanup script:
.\Remove-StaleDisabled.ps1 -ReportOnly -ForceEmail
When an object is found in the Disabled OU, the script determines where it originally came from using this priority:
- Tracking file -- if the object was seen before, its original OU and move date are stored in
disabled-computers.jsonordisabled-groups.json. - Inventory file -- if the inventory snapshot captured the object before it was moved, the OU is taken from there +
whenChangedas the move date. - whenChanged fallback -- if neither is available, the AD
whenChangedattribute is used as an estimate.
Users are only deleted if they are both past the retention period and disabled. Users that are still enabled in the Disabled OU are flagged in the email as anomalies but are never deleted.
Groups are only deleted if they are both past the retention period and have zero members. Groups that still have members are reported in the email as requiring attention but are never deleted automatically.
The summary email is sent only when both of these are true:
- It is the configured
$EmailDay(defaultMonday), or-ForceEmailwas passed. $SmtpServer,$EmailFrom, and$EmailToare all set.
If smtp-credential.xml is present it is used for authentication; otherwise the message is sent unauthenticated. On the configured day with SMTP unconfigured, a warning is logged.
| File | Description |
|---|---|
computer-inventory.json |
Latest snapshot of all computers + OUs |
user-inventory.json |
Latest snapshot of all users + OUs |
group-inventory.json |
Latest snapshot of all groups + OUs |
disabled-computers.json |
Tracking file for computers in the Disabled OU |
disabled-users.json |
Tracking file for users in the Disabled OU |
disabled-groups.json |
Tracking file for groups in the Disabled OU |
smtp-credential.xml |
DPAPI-encrypted SMTP credentials |
logs/ |
Timestamped log files from each run |
- Windows Server with the ActiveDirectory PowerShell module (
RSAT-AD-PowerShell) - Domain controller or server with AD access
- PowerShell 5.1+
- SMTP server for email (optional)
# Report only (no deletions)
.\Remove-StaleDisabled.ps1 -ReportOnly
# Force email send regardless of day
.\Remove-StaleDisabled.ps1 -ForceEmail
# Both
.\Remove-StaleDisabled.ps1 -ReportOnly -ForceEmail
# Preview deletions without performing them (supports -WhatIf / -Confirm)
.\Remove-StaleDisabled.ps1 -WhatIfRemove-StaleDisabled.ps1 also returns a result object (counts and the removed/kept/stale collections, plus the log path) for pipeline or scripted use.