Offboarding series · Part 1
Automating offboarding in a one-person IT shop
Onboarding gets the attention. The account you forget to disable is the real risk. Here's my one-person-shop offboarding flow, and the 3 steps I keep manual.
I wrote a whole post about automating new-hire onboarding, because that is the part everyone feels. A person starts Monday, and if their account is not ready, you hear about it before your coffee is cold. Offboarding is the opposite. Nobody chases you about the account you forgot to disable. It just sits there, enabled, holding a license and a set of keys, until the day it becomes a problem.
That asymmetry is the whole reason offboarding is worth automating. The failure is silent, so it hides. I once went looking for stale accounts. I found one that had stayed enabled for months after the person walked out the door. Nothing bad came of it. That is not the point. The point is that I had no system, so I was relying on memory, and memory is exactly the thing that fails when someone leaves in a hurry.
Deprovisioning is the offboarding half of identity management: cutting off a departing person’s access and reclaiming the resources they held. Here is the flow I built for it, what each step actually protects, and the parts I deliberately keep in human hands.
Key takeaways
- Offboarding fails silently, which makes it a bigger security and cost risk than onboarding.
- Disable and preserve first; deleting an account early destroys the SID that owns files and mailboxes.
- Disabling the on-prem account does not end live Microsoft 365 sessions. You have to revoke those separately.
- Reclaiming one unused license pays for itself immediately, and stale seats add up fast.
- Keep the legal hold, the data handoff, and the final delete as manual decisions.
Why is offboarding riskier than onboarding?
Because a botched onboarding is loud and a botched offboarding is quiet. When onboarding breaks, a new hire cannot log in and someone escalates within the hour, so it gets fixed. When offboarding breaks, a former employee keeps access nobody is watching, a license keeps billing, and there is no one on the other end to complain. The cost is real; it just never announces itself.
For a small shop this matters more, not less. There is no separate security team running an access review to catch what you missed. You are the access review. So the safest move is to take the one moment you reliably know about, the day the person leaves, and make a script do everything you would otherwise have to remember.
What has to happen the moment someone leaves?
Five things, in order: cut off new logins, kill the sessions already running, preserve what the person owned, reclaim what costs money, and record what you did. The ordering is deliberate. Access first, because that is the risk. Preservation before deletion, because deletion is the one step you cannot walk back.
| Step | What it protects |
|---|---|
| Disable the account | Blocks any new login |
| Revoke live sessions | Ends access that is already open |
| Convert the mailbox | Preserves history and records |
| Reclaim the license | Stops paying for a seat nobody uses |
| Log the change | Gives you an audit trail |
I keep this as an ordered checklist in the script itself, not in my head and not in a document. The checklist is the system. If it is not in the script, it does not happen reliably, and “reliably” is the entire value. A manual step you perform ninety percent of the time is a step that fails on the tenth person, and the tenth person is always the messy departure you least want to fumble.
How do you disable an account the right way?
Disable it, reset its password, move it somewhere auditable, and record its group memberships before you strip them. Disabling blocks new logins; the password reset burns any cached or saved credential; the move gets the account out of the active population so it cannot hide; and capturing the groups first means you can answer “what could this person reach” later, during a rehire or an audit.
The one rule I will not bend: disable, do not delete. A deleted account loses the SID that owned the person’s files, mailbox, and group memberships, and getting that back is far more work than it sounds. Disable is reversible. Delete is a decision for later, made on purpose. A grace period is the stretch of time an account stays disabled but not gone, long enough that you are sure nothing still depends on it.
# Runs against a departing user by sAMAccountName.
$user = Get-ADUser -Identity $sam -Properties MemberOf
# 1. Disable, don't delete. Reversible now; delete on purpose later.
Disable-ADAccount -Identity $user
# 2. Reset to a random password so a saved credential cannot be reused.
$random = [System.Web.Security.Membership]::GeneratePassword(24, 6)
Set-ADAccountPassword -Identity $user -Reset -NewPassword `
(ConvertTo-SecureString $random -AsPlainText -Force)
# 3. Move to a quarantine OU with no logon rights, easy to audit.
Move-ADObject -Identity $user.DistinguishedName `
-TargetPath 'OU=Disabled Users,DC=example,DC=local'
# 4. Record group memberships, then remove them.
$user.MemberOf | ForEach-Object {
Remove-ADGroupMember -Identity $_ -Members $user -Confirm:$false
}
Does disabling the account log them out of Microsoft 365?
No, and this is the gap that surprises people. If your identities sync to Microsoft 365, disabling the on-prem account eventually flows up as a blocked sign-in, but any session or refresh token the person already holds keeps working until it expires on its own. That window can be hours. For a departure that is anything other than friendly, hours is too long.
So the offboarding script revokes sessions explicitly rather than trusting the account state to catch up.
# Disabling on-prem does NOT end live cloud sessions. Revoke them.
Connect-MgGraph -Scopes 'User.RevokeSessions.All', 'User.ReadWrite.All'
Revoke-MgUserSignInSession -UserId $upn
That call, Revoke-MgUserSignInSession, invalidates the refresh tokens, so the next time any app tries to renew, it fails and the person is out. Revoking sessions is the fast half of the problem. The slower half, walking every other place a person still has access, from the VPN to the dozen SaaS tools nobody put in a spreadsheet, is a big enough topic that it gets its own post later in this series.
What about the mailbox and the person’s files?
Convert the mailbox, do not delete it. A departing person’s mailbox is usually the single most requested thing after they leave, because their replacement needs the history and a manager needs to answer the questions that were in flight. Convert it to a shared mailbox and delegate access to whoever inherits the role. A shared mailbox is one several people can open from their own Outlook without it holding a paid license of its own.
# Convert to a shared mailbox so the history stays reachable.
Set-Mailbox -Identity $upn -Type Shared
A shared mailbox under the size cap does not need its own license, which conveniently sets up the next step. Files are the same principle: reassign ownership of anything on a shared drive or in the person’s own storage to a manager before anything gets cleaned up, so nothing important leaves with them.
How do you reclaim the licenses, and why bother?
Remove the assigned licenses so the seat goes back into the pool for the next hire. This is the step that quietly pays for the whole exercise. A single Microsoft 365 E3 seat runs about 36 dollars per user per month at Microsoft’s 2026 published list price. One seat you forgot to reclaim is over 400 dollars a year spent on someone who left. Two or three of those and the automation has paid for the afternoon it took to write.
# Return the seat to the pool. Do this after the mailbox is shared.
$sku = (Get-MgUserLicenseDetail -UserId $upn).SkuId
Set-MgUserLicense -UserId $upn -RemoveLicenses $sku -AddLicenses @{}
Order matters here. Convert the mailbox to shared first, then pull the license, or you can strip access to a mailbox you were about to hand to someone else.
What should stay manual?
Three things, and they are the same shape as the manual steps I keep in onboarding: the ones where judgment beats speed. First, a legal or records hold. If the person’s data might be subject to a retention obligation or a public-records request, that is a decision to make with the right people, not a step to automate away. Second, the data handoff itself, because a human has to decide what actually matters and who should get it. Third, the final delete, made deliberately and only after the account has sat disabled long enough that you are sure nothing still depends on it.
Everything else, the disable, the session revoke, the mailbox conversion, the license reclaim, the logging, runs from the script. The machine does the fast, boring, easy-to-forget work. I do the small number of things that need a person.
What broke, and what I would change
The hardest part of offboarding is not the script. It is finding out the offboarding needs to happen. HR knows someone left; you find out when their manager needs something. Closing that gap is more valuable than any code, and it is the same intake problem onboarding has, just running in reverse. The best version of this ties the trigger to a system HR already updates, so you are not depending on a hallway conversation.
The other thing I learned, and would tell my earlier self: resist deleting anything on day one. The instinct to tidy up is strong. Every time I have deleted an account quickly, I have regretted it within the month, when a file, a calendar, or a mailbox turned out to still matter. Disabled and boring beats deleted and gone.
FAQ
Should you delete or just disable a departing employee’s account?
Disable it. A disabled account is reversible and keeps the SID that owns the person’s files, mailbox, and group memberships. Delete only later, deliberately, once you are certain nothing still depends on it.
How fast does offboarding need to run?
Immediately for access, patiently for cleanup. Disable the account and revoke live sessions the moment the person leaves, especially for an involuntary departure. Mailbox conversion, license reclaim, and eventual deletion can follow on a calmer schedule.
Does blocking the on-prem account sign them out of Microsoft 365?
Not right away. Existing tokens keep working until they expire, so revoke sessions explicitly with a call like Revoke-MgUserSignInSession rather than assuming the synced account state will cut access off in time.
Do you keep paying for a former employee’s mailbox?
Not if you convert it to a shared mailbox. Under the size cap, a shared mailbox needs no license, so you keep the history reachable and still free up the seat.