Inactive users still holding Microsoft 365 licenses
Seats that went quiet: the user was real and active once, then changed roles, went on leave or moved to another tool, and the licensed account stopped signing in to Exchange, OneDrive, SharePoint and Teams. Without a last-activity check across those workloads, the seat looks fine in the admin center.
Why idle seats stay invisible
Inactivity is a join problem. A user can be absent from the sign-in logs but still show up in a mailbox report, or vice versa, so any single report understates or overstates the problem. Judging a seat idle honestly means taking the most recent of the sign-in timestamp and the per-workload last-activity dates, per user, and comparing that against a threshold.
Role changes, long leaves, contractors who rolled off without a leaver process, shared accounts whose purpose ended: none of these disable the account, so the offboarding checks never trigger. The license renews monthly against an account nobody uses.
Detect it manually
With Entra ID P1, Graph supports filtering users by their last sign-in timestamp directly:
Connect-MgGraph -Scopes 'User.Read.All', 'AuditLog.Read.All'
$cutoff = (Get-Date).AddDays(-90).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ')
Get-MgUser -All -Filter "signInActivity/lastSignInDateTime le $cutoff" -Property 'displayName,userPrincipalName,signInActivity' |
Select-Object DisplayName, UserPrincipalName- Graph does not allow combining the signInActivity filter with other filterable properties, so restricting the list to licensed users happens client-side, and users who never signed in at all are not matched by this filter.
- lastSignInDateTime counts interactive sign-in attempts including failed ones; sign-ins are not the whole picture either, so a thorough audit also pulls the Exchange, OneDrive, SharePoint and Teams usage reports and takes the most recent activity per user.
How LicenseMeter detects it
The nightly sync joins sign-in activity with the Exchange, OneDrive, SharePoint and Teams usage reports into a single last-activity timestamp per user. The rule fires when that timestamp is older than the workspace's inactivity window: 90 days by default, adjustable per workspace between 30 and 180 days, and each finding's title states the exact day count.
Detection degrades gracefully instead of failing. Without Entra ID P1, signInActivity is unavailable and inactivity falls back to the per-workload usage reports. If the tenant also conceals report display names, per-user findings are impossible, so the engine emits one aggregate finding stating how many of the tenant's users show no activity, along with the admin-center setting that restores per-user detail.
What it costs
Each inactive user is priced at the full monthly cost of every SKU they hold, from the editable per-tenant price book prefilled with list-price estimates. That turns a list of stale accounts into a monthly euro figure finance can act on.
In the 155-person sample tenant, idle and never-active seats together waste € 751,58 a month across Microsoft 365 and connected apps.
Sample figures come from the deterministic demo workspace, not from customer data. The waste calculator turns your own seat count into an estimate.
Related waste patterns
See which of your seats match this pattern.
Connect read-only and the free scan lists every affected account in your tenant, priced per seat and per month, with a PowerShell remediation script your IT reviews and runs.
After the free scan, 14 days of full monitoring, free. No credit card, read-only access.