
Disable, Move, and Delete an Active Directory User Safely with PowerShell
Before you run this
This guide walks the standard three-stage offboarding of a single Active Directory user account: disable it (so nobody can log in), move it to a holding OU, and — only after a retention period — delete it. That order is deliberate. Disabling is instant and fully reversible; deletion is not.
These cmdlets change directory objects, so you need an elevated PowerShell session running as an account with rights to modify the target user — Domain Admin, or a delegated account with the specific permissions to disable/move/delete in the OUs involved. You also need the ActiveDirectory module, which ships with RSAT (Remote Server Administration Tools). Run these from a domain-joined admin workstation or a domain controller.
Test on a throwaway test user first — create one like testuser01, run the whole sequence against it, and confirm each stage behaves as you expect before you touch a real account. Read each command before you paste it. In particular:
Disable-ADAccountis reversible withEnable-ADAccount.Move-ADObjectis reversible by moving it back, if you record the original OU first.Remove-ADUseris destructive. Without the AD Recycle Bin enabled, a deleted user is effectively gone — SID, group memberships, attributes, and any resources tied to that SID. Do not run the delete stage on the same day you disable the account. Give yourself a retention window.
Every command below includes -WhatIf guidance so you can preview the change before committing it.
Assumptions
- Windows Server 2016 or later domain, functional AD DS.
- Windows PowerShell 5.1 with the ActiveDirectory module available (
Import-Module ActiveDirectory— 5.1 usually auto-loads it). - Domain
example.com, and a holding OU already created atOU=Disabled Users,DC=example,DC=com. Create that OU yourself in ADUC or withNew-ADOrganizationalUnitif it doesn't exist. - A single target user with
sAMAccountNamejdoe. Replacejdoe,example.com, and the OU strings with your own values throughout.
Confirm the module loads:
Import-Module ActiveDirectory
Get-ADUser jdoe # sanity check: does this user exist and resolve?
Stage 1 — Disable the account
This is the first thing you do the moment someone leaves. It's immediate, safe, and reversible. I also stamp the description with the date and a note, which makes the holding OU self-documenting later.
Preview first with -WhatIf:
Disable-ADAccount -Identity jdoe -WhatIf
If that reports the right account, run it for real and annotate:
# Disable login
Disable-ADAccount -Identity jdoe
# Stamp a note so the holding OU explains itself
$note = "Disabled $(Get-Date -Format 'yyyy-MM-dd') - offboarding"
Set-ADUser -Identity jdoe -Description $note
Optional: record and remove group memberships
Group memberships are the part people forget. Removing them cuts off access that lives in groups (file shares, distribution lists, app roles), and if you ever delete the account, you'll want a record of what it belonged to. Capture it to a file before you remove anything:
# Save current memberships for the record
Get-ADPrincipalGroupMembership jdoe |
Select-Object -ExpandProperty Name |
Out-File "C:\path\to\jdoe-groups.txt"
You can leave memberships in place during the disabled/holding period if your policy prefers that (it makes a full restore trivial). If you do want to strip them, preview first:
# Preview removal of all non-primary group memberships
Get-ADPrincipalGroupMembership jdoe |
Where-Object { $_.Name -ne 'Domain Users' } |
ForEach-Object {
Remove-ADPrincipalGroupMembership -Identity jdoe -MemberOf $_ -WhatIf
}
Drop the -WhatIf to apply. Note that a user's primary group (usually Domain Users) can't be removed this way while it's the primary — that's expected, and you normally leave it alone.
Stage 2 — Move to a holding OU
Moving the disabled account out of its working OU gets it out of the way and, importantly, out from under any GPOs or delegated management scoped to the original OU. Move it into your dedicated Disabled Users OU.
Record the original location first — this is your undo path:
# Note where it lives now, in case you need to move it back
(Get-ADUser jdoe).DistinguishedName
Write that value down. Then preview and move:
$target = "OU=Disabled Users,DC=example,DC=com"
# Preview
Get-ADUser jdoe | Move-ADObject -TargetPath $target -WhatIf
# Apply
Get-ADUser jdoe | Move-ADObject -TargetPath $target
Piping Get-ADUser into Move-ADObject hands over the object's distinguished name for you, so you don't have to type the full DN.
Stage 3 — Delete, after the retention period
Only reach this stage after your retention window (30, 60, 90 days — whatever your policy says) and after confirming nothing else depends on the account: no services running under it, no mailbox you still need, no resources owned by its SID.
Before deleting, decide whether the AD Recycle Bin is enabled in your forest. It's the difference between a recoverable mistake and a permanent one. Check it:
Get-ADOptionalFeature -Filter "name -eq 'Recycle Bin Feature'" |
Select-Object Name, EnabledScopes
If EnabledScopes is populated, the Recycle Bin is on. Enabling it is a separate, forest-wide, one-way decision — see Microsoft Learn for "Enable Active Directory Recycle Bin" before you touch it; don't enable it casually as part of an offboarding.
Remove-ADUser prompts for confirmation by default, which is exactly what you want here. Preview, then run:
# Preview only — makes no change
Remove-ADUser -Identity jdoe -WhatIf
# Delete for real — you'll be prompted to confirm
Remove-ADUser -Identity jdoe
I deliberately do not add -Confirm:$false here. Leaving the prompt in place is a feature, not friction.
Verify each stage
After disable — the account should show as disabled:
Get-ADUser jdoe -Properties Enabled, Description |
Select-Object Name, Enabled, Description
Enabled should be False.
After move — the DN should now sit under the holding OU:
(Get-ADUser jdoe).DistinguishedName
After delete — the lookup should fail because the object is gone:
Get-ADUser jdoe # expect: "Cannot find an object with identity"
Undo
Re-enable a disabled account:
Enable-ADAccount -Identity jdoe
Move it back to the original OU (using the DN you recorded in Stage 2):
Get-ADUser jdoe | Move-ADObject -TargetPath "OU=Staff,DC=example,DC=com"
Restore a deleted user — only possible if the AD Recycle Bin was enabled before the deletion. Find the tombstoned object and restore it:
# Find the deleted object
Get-ADObject -Filter 'sAMAccountName -eq "jdoe"' -IncludeDeletedObjects
# Restore it (use the ObjectGUID or DN from the previous command)
Restore-ADObject -Identity "<ObjectGUID-from-above>"
If the Recycle Bin was not enabled, there is no supported PowerShell restore — recovery means an authoritative restore from a system-state backup of a domain controller, which is a much bigger operation. That's the whole reason the delete stage comes last and separate.
For exact parameters and edge cases, see Microsoft Learn for Disable-ADAccount, Move-ADObject, Remove-ADUser, and Restore-ADObject.
Runs enterprise networks and security for a living, and writes Shore Up to turn two decades of hands-on Linux, Windows and mail-server work into guides you can actually use.
More about the author →Was this article helpful?
Tap a star — no sign-in needed.
Be the first to rate this article.
