Offboarding done by hand gets done differently every time, and the steps people forget are always the same ones: group memberships left in place, a mailbox still receiving, an account disabled but never actually reviewed.
This is a script that does it identically every time, logs what it did, and supports -WhatIf so you can show someone exactly what will happen before it happens.
Quick Facts
- Disable, don’t delete. Deletion loses the SID, and with it access to anything owned by that account.
- Record group memberships before removing them. You will be asked what someone had access to.
- Move the account to a dedicated OU so policy and reporting can treat leavers as a group.
- Reset the password to something random. A disabled account with a known password is still a risk.
- Support
-WhatIf. Being able to demonstrate the outcome beforehand is what gets this approved.
What offboarding should actually do
| Step | Why |
| Disable the account | Stops authentication immediately |
| Reset the password | A known password on a disabled account is still an exposure |
| Record group memberships | You’ll be asked later what they had access to |
| Remove from groups | Stops access if the account is ever re-enabled |
| Move to a Leavers OU | Separates policy, reporting and retention |
| Set the description | Who left, when, and who authorised it |
| Hide from address list | Stops people emailing a dead mailbox |
| Log everything | Evidence the process ran |
The script
[CmdletBinding(SupportsShouldProcess)]
param(
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string]$SamAccountName,
[ValidateNotNullOrEmpty()]
[string]$LeaversOU = 'OU=Leavers,DC=example,DC=com',
[string]$Ticket = 'No ticket supplied',
[ValidateScript({ Test-Path (Split-Path $_) })]
[string]$LogPath = 'C:\Logs\Offboarding.csv'
)
Import-Module ActiveDirectory
$user = Get-ADUser -Identity $SamAccountName -Properties MemberOf, Description -ErrorAction Stop
$groups = $user.MemberOf | Get-ADGroup | Select-Object -ExpandProperty Name
if ($PSCmdlet.ShouldProcess($user.Name, 'Offboard user')) {
# 1. Disable
Disable-ADAccount -Identity $user
# 2. Random password
$pw = [System.Web.Security.Membership]::GeneratePassword(24,6)
Set-ADAccountPassword -Identity $user -Reset `
-NewPassword (ConvertTo-SecureString $pw -AsPlainText -Force)
# 3. Strip group memberships (primary group cannot be removed)
foreach ($g in $user.MemberOf) {
Remove-ADGroupMember -Identity $g -Members $user -Confirm:$false -ErrorAction SilentlyContinue
}
# 4. Description for the audit trail
Set-ADUser -Identity $user -Description "Offboarded $(Get-Date -Format 'yyyy-MM-dd') - $Ticket"
# 5. Move to Leavers OU
Move-ADObject -Identity $user.DistinguishedName -TargetPath $LeaversOU
# 6. Log it
[PSCustomObject]@{
Date = Get-Date -Format 'yyyy-MM-dd HH:mm'
User = $user.SamAccountName
Name = $user.Name
Ticket = $Ticket
Groups = ($groups -join '; ')
RunBy = $env:USERNAME
} | Export-Csv -Path $LogPath -NoTypeInformation -Append
}
Run it with -WhatIf first and it reports exactly what it would do without touching anything. Which is how you get sign-off from someone nervous about automation touching Active Directory.
.\Invoke-Offboarding.ps1 -SamAccountName j.smith -Ticket 'HR-4821' -WhatIf
The parts people get wrong
- Deleting instead of disabling. A deleted account’s SID is gone, and with it the ability to reassign file ownership or reopen its mailbox cleanly.
- Not recording groups before removing them. Six weeks later someone asks what access the leaver had, and the answer is unrecoverable.
- Forgetting the primary group.
Remove-ADGroupMembercan’t remove Domain Users while it’s the primary group. That’s expected, not a failure. - Leaving the mailbox visible. Hiding from the address list stops colleagues emailing into a void.
- No log. If it isn’t written down, you can’t demonstrate the process ran.
Beyond Active Directory
On-premises AD is one part. Depending on your environment you’ll also want to revoke Microsoft 365 sessions and licences, remove the account from any SaaS platforms not covered by SSO, and deal with MFA registrations:
# Microsoft Graph - revoke sessions immediately
Revoke-MgUserSignInSession -UserId '[email protected]'
Session revocation matters more than people expect. Disabling the AD account doesn’t invalidate an existing cloud token, so someone can remain signed in on a phone for hours afterwards.
Glossary
| Term | What it means |
| SID | Security Identifier. The unique ID behind an account. Lost permanently on deletion. |
| Primary group | The group an account counts as its default. Cannot be removed while set. |
| Leavers OU | A dedicated organisational unit for departed staff, simplifying policy and retention. |
-WhatIf | Shows what a command would do without doing it. |
| Session revocation | Invalidating existing cloud sign-in tokens so active sessions end. |
| Soft delete | Disabling and retaining an account rather than removing it. |
Frequently asked questions
Should I delete leavers’ accounts?
Not immediately. Disable, strip access and move them, then delete after a retention period. Typically 30 to 90 days. Once you’re sure nothing needed the SID.
Why reset the password on a disabled account?
Defence in depth. If someone re-enables it accidentally, or a sync process does, you don’t want the old password still working.
Can I run this against several users at once?
Yes. Accept an array of SamAccountNames, or pipe a CSV in. Keep the per-user logging so the audit trail stays intact for each.
What if the user owns files or is a group manager?
Handle it before offboarding. Reassign file ownership and group management first, or you’ll be reopening the account later to do it.
Does disabling the AD account stop Microsoft 365 access?
Not immediately. Existing tokens stay valid until they expire. Revoke sign-in sessions explicitly if the departure is immediate or contentious.
Gear We Recommend
Testing AD automation safely needs a lab you can break. Here’s ours.
Browse our Home Lab picks on AmazonAs an Amazon Associate, TechyGeeksHome earns from qualifying purchases
Disclosure: this post may contain affiliate links. If you buy through one of them, we may earn a small commission at no extra cost to you. We only recommend products we’ve tested or genuinely rate.
Discover more from TechyGeeksHome
Subscribe to get the latest posts sent to your email.