๐ณ Recipe ยท Licensing & Cost Optimization
Identify Departed Employees and Reclaim Microsoft 365 Licenses
Find disabled accounts still consuming licenses and free them up to reduce billing
Complexity
Intermediate
Impact
cost-savings + license-hygiene + offboarding + compliance
Context
Why This Matters
Departed employees often leave behind active Microsoft 365 licenses even after their accounts are disabled. Every unclaimed license continues to bill against your tenant until it is explicitly unassigned. For tenants with dozens to thousands of users, these orphaned assignments can quickly add up to hundreds or thousands of dollars per month in wasted spend.
This recipe walks you through systematically identifying departed employees โ using a combination of disabled-account state, recent audit log activity, and HR-provided lists โ and reclaiming their licenses so they can be reassigned or dropped from your subscription at renewal.
Run this monthly as part of your license hygiene cadence, or on demand when HR notifies IT of terminations.
Expected Outcomes
- A list of all disabled user accounts that still hold Microsoft 365 license assignments
- Cross-referenced audit log data showing when each account was disabled and by whom
- Licenses removed from departed employees and returned to the available pool
- A documented report suitable for finance or audit review
- Lower ongoing license costs at the next billing cycle
Risks & Considerations
Before you reclaim
- Preserve mailbox and OneDrive data first. Removing a license can delete the mailbox after 30 days and the OneDrive after retention expires. Convert the mailbox to shared, set a retention hold, or export data before unassigning.
- Disabled โ departed. Some disabled accounts are on leave, maternity, or awaiting rehire. Confirm departure status with HR before reclaiming.
- Group-based licenses. If the license is assigned via a group, you must remove the user from the group โ unassigning directly will fail or be re-applied automatically.
- Litigation hold. Accounts under e-discovery or legal hold must retain their license (or be converted to inactive mailboxes) until the hold is released.
Compliance
Document every reclamation action with timestamps and the approving manager/HR contact. This is often required for SOX, ISO 27001, or SOC 2 access-review controls.
Required Permissions
| Permission | Why It's Needed |
|---|---|
| User.Read.All | Enumerate all users and read their accountEnabled state and assigned licenses |
| Directory.ReadWrite.All | Call assignLicense to remove SKUs from departed users |
| AuditLog.Read.All | Query directoryAudits for recent 'Disable account' events to confirm departure timing |
| Organization.Read.All | Resolve SKU IDs to friendly product names via subscribedSkus |
| Group.Read.All | Detect group-based license assignments that must be resolved at the group level |
The fastest way to get this done: just ask Dex. Copy the prompt below and paste it into your Dex conversation.
For IT Admins
Paste into Dex Pro
Reclaim licenses via the Microsoft 365 Admin Center
Sign in to admin.microsoft.com as a Global Admin or License Admin.
In the left navigation, go to:
Users โ Active users
Click Filter and select Sign-in blocked to show disabled accounts. These are your primary candidates for departed employees.
Click Export users (top toolbar) to download a CSV. Open it in Excel and filter for rows where
Block sign-inis Yes andLicensesis non-empty.Cross-reference the list with HR's termination report. Flag confirmed departures.
For each confirmed departed employee:
- Click the user's name to open their profile.
- Go to the Licenses and apps tab.
- Uncheck every assigned license.
- Click Save changes.
Verify reclamation by returning to:
Billing โ Licenses
The Available count for each SKU should have increased.
Optional: convert the user's mailbox to a shared mailbox before removing the Exchange license to preserve email access for the team.
Reclaim licenses using Microsoft Graph
Step 1 โ Find disabled users with active licenses
GET https://graph.microsoft.com/v1.0/users?$filter=accountEnabled eq false&$select=id,displayName,userPrincipalName,assignedLicensesPaginate with @odata.nextLink if your tenant has more than 100 disabled users. In the response, keep only users where assignedLicenses is non-empty.
Step 2 โ Correlate with recent disable events
GET https://graph.microsoft.com/v1.0/auditLogs/directoryAudits?$filter=activityDisplayName eq 'Disable account'&$top=50&$orderby=activityDateTime descThis confirms when each account was disabled and by whom โ useful for audit trails.
Step 3 โ Resolve SKU IDs to product names
GET https://graph.microsoft.com/v1.0/subscribedSkus?$select=skuId,skuPartNumber,consumedUnits,prepaidUnitsStep 4 โ Remove licenses from a departed user
POST https://graph.microsoft.com/v1.0/users/{user_id}/assignLicense
Content-Type: application/json
{
"addLicenses": [],
"removeLicenses": ["c42b9cae-ea4f-4ab7-9717-81576235ccac"]
}Expected response: 200 OK with the updated user object. If the license was group-assigned, you'll receive a 400 with Error: License cannot be removed directly โ remove the user from the licensing group instead via DELETE /groups/{group_id}/members/{user_id}/$ref.
Automate with PowerShell and Microsoft Graph
The Microsoft Graph PowerShell SDK is the supported replacement for the retired MSOnline and AzureAD modules. The script below:
- Connects with delegated permissions
- Enumerates all disabled users with licenses
- Outputs a CSV report for review
- Optionally removes licenses with a
-WhatIfsafety switch
Prerequisites
Install-Module Microsoft.Graph -Scope CurrentUser
Connect-MgGraph -Scopes "User.Read.All","Directory.ReadWrite.All","AuditLog.Read.All","Organization.Read.All"Review before you reclaim
Always run the script in report-only mode first (-ReportOnly). Review the CSV with HR and finance, then re-run with -Reclaim to actually remove licenses.
Next steps