How to find wasted Microsoft 365 licenses (2026 guide)
Microsoft raised Microsoft 365 list prices on July 1, 2026 — Microsoft 365 E3 to $39 and E5 to $60 per user, per month. For most organizations the bigger problem isn't the new price; it's how many of those seats are doing nothing. Gartner estimates organizations waste 25–30% of SaaS license spend on unused or underutilized licenses. On a 100-seat E3 tenant, that's roughly $9,000 a year hiding in plain sight.
This guide shows exactly where M365 license waste accumulates, how to find it with read-only Microsoft Graph queries, and — the part most teams skip — how to turn the findings into a dollar figure your finance team will actually act on.
The five places license waste hides
- Unassigned purchased seats. You bought the seats; nobody's assigned to them. The cleanest refund at renewal.
- Disabled-but-licensed accounts. Blocked sign-in, but still consuming (and billing for) a license every month.
- Never-signed-in users. Provisioned, licensed, and never logged in once.
- Inactive users. No sign-in in N days — you choose the threshold (30/60/90).
- Over-provisioning. Users on E5 who only ever needed E3 ($21/user/mo back), or users carrying two base plans at once.
Step 1 — Read your license inventory
Everything here is read-only. Install the Microsoft Graph PowerShell SDK and connect with read scopes:
Install-Module Microsoft.Graph -Scope CurrentUser
Connect-MgGraph -Scopes "Organization.Read.All","User.Read.All","Directory.Read.All","AuditLog.Read.All"
# Purchased vs assigned per SKU
Get-MgSubscribedSku | Select-Object SkuPartNumber,
@{n='Purchased';e={$_.PrepaidUnits.Enabled}},
@{n='Assigned'; e={$_.ConsumedUnits}}
The gap between PrepaidUnits.Enabled and ConsumedUnits is your unassigned-seat waste — the fastest win.
skuPartNumber values are full of legacy traps. Microsoft 365 Business Standard is literally O365_BUSINESS_PREMIUM; Business Premium is SPB. Map them carefully or your report will mislabel seats.
Step 2 — Pull users, licenses, and activity
Get-MgUser -All -Property `
id,displayName,userPrincipalName,accountEnabled,assignedLicenses,createdDateTime,signInActivity
Two gotchas that bite most homegrown scripts:
signInActivityrequires Microsoft Entra ID P1. On a non-premium tenant, including it makes Graph return403for the entire query. Wrap it: try withsignInActivity, and on failure retry without it (you can still find disabled and unassigned waste).- Free/self-service SKUs report a giant "unlimited" seat count. Power Automate Free and friends can show millions of "prepaid" units. Exclude any SKU whose enabled count is implausibly large before you sum unassigned seats.
Step 3 — Turn seats into dollars
This is the step that separates a useful audit from a CSV nobody reads. "47 inactive users" gets a shrug. "$13,056/year recoverable" gets a meeting. Map each skuPartNumber to its real price (use your contracted/regional rate, not just list), then:
| Finding | Recoverable $ / month |
|---|---|
| Unassigned seats | unassigned × unit price |
| Disabled + licensed | sum of those users' license prices |
| Never signed in | sum of those users' license prices |
| Inactive > N days | sum of those users' license prices |
Annualize (×12) for the headline. Keep over-provisioning (E5→E3, plan overlap) as an advisory section so your headline number stays conservative and defensible.
Step 4 — Act, then keep it clean
Reclaim unassigned seats at renewal, strip licenses off disabled accounts, offboard never-signed-in leftovers, and review inactive users with their managers. Then re-run monthly — waste creeps back the moment offboarding slips.
Skip the assembly
SeatScout runs every check above in one command and produces a dollar-quantified, CFO-ready report — read-only, entirely inside your own tenant. There's a free tier.
Get SeatScout →FAQ
Can I find unused M365 licenses without Entra ID P1?
Partly. Without P1 you can't read sign-in activity, so inactive/never-signed-in detection is unavailable — but you can still find disabled-but-licensed accounts and unassigned purchased seats, which are often the largest, cleanest wins.
Is querying this data safe?
Yes — all of it is read-only Microsoft Graph. None of the queries above modify your tenant. Reclaiming licenses is a separate, deliberate step you control.
How much can a typical org recover?
Gartner pegs SaaS waste at 25–30% of spend; license-optimization vendors report finding 10–30% of M365 spend as waste in most environments. The exact figure depends on offboarding hygiene and how aggressively E5 was rolled out.
Sources: Microsoft 365 2026 pricing (Microsoft Licensing); average SaaS license waste 25–30% (Gartner, as cited by license-optimization vendors). SeatScout is independent and not affiliated with Microsoft.