How I used Powershell Scripting to clean up neglected Active Directory Domains
Recently had to tidy up some sadly neglected AD Domains which reported several times the number of actual users in the Organisations than were actually employed.
As well as the user accounts it was required to archive off the users network folders and, where applicable, Exchange 2010/2013 mailboxes.
Took a two step approach:
Step 1 – Identify accounts not logged in over previous 60 day period
First just a straight search on one Domain, specifying the DC, for user accounts not seen in 60 days:
Search-ADAccount -server your_domain_controller -AccountInactive -TimeSpan 60.00:00:00 | where {$_.ObjectClass -eq 'user'} | Out-GridView
The other Domains required an OU excluding, hence the filter:
Search-ADAccount -AccountInactive -filter{distinguishedname -notmatch 'part_of_your_DN'} -TimeSpan 60.00:00:00 | where {$_.ObjectClass -eq 'user'} | Out-GridView
I like to output to Grid View as a personal preference, then copying into Excel.
Having got my lists of inactive user accounts:
- Cross checked them against the helpdesk to ensure leaver tickets had been raised at some point.
- Confirmed the rest were not service or other required accounts.
- Remainder were passed to HR to ensure not on sick, maternity or otherwise still employed.
This left me with lists of all users who should not have had active accounts – saved as csv files for import into Step 2 (single column samAccountName with ‘samacc’ as header.
Step 2 – disable accounts, move to dead users OU, archive home folders, archive mailbox:
The lines that perform the actual actions are currently commented out with a single hash – again, a personal preference so I can see what’s going to happen before it does (rather than -whatif).
There are some assumptions made and modifications required – log file dead_users.txt in listed location, dead_users.csv input file as specified, couple of OUs will need adjusting to suit (should be self evident).
$users = @() Remove-Item c:\scripts\output\dead_users.txt Add-Content c:\scripts\output\dead_users.txt "SAMACC,DISPLAYNAME,DISABLE,MOVE DEAD,MAILBOX,HOMEDIR,EXIST,DESCRIPTION" Import-Csv C:\Scripts\input\dead_users.csv | ForEach-Object {$Sam = $_.samacc $users += Get-ADUser -filter {(samaccountname -like $Sam)} | select name, samaccountname, distinguishedname, enabled, displayname } foreach($i in $users){ $Result = "" $Sam = $i.samaccountname $Display = $i.displayname If($i.enabled) { $Enabled = "DISABLE" #Disable-ADAccount -Identity $Sam } ELSE {$Enabled = "NO ACTION"} #### Move to Dead Users #### If ($i.distinguishedname.contains("AA_Dead")){$Move = "NO ACTION"} ELSE {$Move = "MOVE"} #If ($i.distinguishedname.contains("OU=South")){Move-ADObject -Identity $i.distinguishedname -TargetPath "ou=south,ou=aa_dead users,dc=yourdomain,dc=com"} #else {Move-ADObject -Identity $i.distinguishedname -TargetPath "ou=north,ou=aa_dead users,dc=yourdomain,dc=com" } #### Mailbox #### $distname = $i.distinguishedname $props = [adsi]"LDAP://$distname" $desc = $props.Properties['description'] $MyName = $props.Properties['displayname'] if($props.Properties['homemdb']){$mailbox = $props.Properties['homemdb'] $mailbox = $mailbox.split("="); $mailbox = $mailbox[1] $mailbox = $mailbox.split(","); $mailbox = $mailbox[0]} #new-item -type directory -path \\YourPSTsharePath\$Sam #New-MailboxExportRequest -Mailbox $Sam -FilePath "\\YourPSTsharePath\$Sam\$Sam.pst" ELSE {$mailbox = "NA"} #### Home Directory #### if($props.Properties['homedirectory']){$homedir = $props.Properties['homedirectory']} ELSE {$homedir = "NA"} if(Test-Path $homedir){$PathExists = "Exists"} ELSE {$PathExists = "N/A"} IF ($homedir -MATCH "DFS_North") { #Move-Item $homedir '\\YourArchiveFolderLocation' } else { #Move-Item $homedir '\\OtherArchiveFolderLocation' } $Result = "$Sam, $MyName, $Enabled, $Move, $Mailbox, $HomeDir, $PathExists, $desc, $distname" Add-Content c:\scripts\output\dead_users.txt $Result #### To remove the user account uncomment below ### # Remove-ADUser -Identity $Sam -Confirm:$false }
Update
The above assumes you have requisite permissions on the source files – as you generally would.
Experience has taken me to one AD cleanup where only the user had permissions on their folders – not even System or BUILTIN \Administrators.!
In this event you may find my post on the NTFSSecurity module helpful.