Unused licences
Seats nobody uses, and what they cost
The Microsoft 365 seats you are paying for that nobody is using, priced. It finds licensed users with no activity in the window you set, plus seats you have bought and never assigned to anyone, and separates what you could cut today from what can only change at renewal. It never removes a licence.
What it tells you
- Who holds a licence and has not used it inside your idle window, with the evidence per workload rather than a single guess.
- Seats that are paid for and assigned to nobody at all.
- What all of that is worth per month and per year, at Microsoft's list prices for your market.
- What is genuinely reclaimable now against what is locked until the subscription renews, which are very different conversations with a finance team.
- Who cannot be judged at all, and why, instead of being quietly counted as idle.
How it runs
- Sign in. One window, asking for the full set of read permissions the report needs. It does not ask for a smaller set and then come back for more halfway through.
- Set the idle window. One month by default. Seats are priced at Microsoft's list prices built into ShareMaster, which you cannot change in the app; the workbook marks every price as an estimate, and you can edit the Unit price (monthly) cells on its Prices sheet in Excel to use your own.
- It gathers the evidence. Tenant subscriptions and SKUs, who holds what, the Microsoft 365 usage reports per workload, and sign-in activity, which is the only uncapped source and therefore the only way to answer questions longer than 180 days.
- Save the workbook. Thirteen sheets, or fourteen when an earlier run for the same tenant adds New since last run, arranged so Summary and Savings answer the question and the rest show the working.
How it works
It reads, in order: the tenant's subscribed products and seat counts, which is the one read the report cannot do without; any groups you excluded; every licensed user with their last sign-in; deleted users still holding seats; and subscription renewal and trial dates. If your tenant cannot supply sign-in activity, the users are read again without it and sign-in is marked unavailable. It then reads six Microsoft 365 usage reports (active users, email, Office apps, Teams devices, mailbox usage and Copilot), each over the shortest period that covers your idle window, up to 180 days, and finally the Exchange mailbox activity.
If the usage reports have names concealed, their per-user figures cannot be matched to anyone, so all of them are set aside and the Data sources sheet says why, rather than everyone appearing idle. Each user is then judged against the date the usage data was current as of, in this order: excluded; holding only free products; deleted, disabled or with an assignment error; could not be judged; in use or idle; too new to judge; never used. Never used is decided only from sign-in or Exchange activity, the sources without a 180 day cap.
Confidence is High when workload activity and sign-in were both read, Medium with workload activity only, Low with sign-in only, and None when nothing could be read. A user holding a product that has no usage report is capped at Low.
Unassigned seats are the seats bought minus the seats assigned. Disabled, deleted and errored users count as confirmed savings; idle and never used count as potential. Prices are the published list prices built into the app for your market and cannot be edited, and a product with no bundled price is not costed. Whether a saving can be made now or at renewal follows the price's billing term. A check for holds runs after the verdicts; if it fails, holds read as unknown. The workbook goes into History when the run ends, and when an earlier run exists it adds a sheet of what is new since then.
What you get
An Excel workbook, named like contoso-unused-licences-20260901-142207.xlsx, kept in Report History whether or not you save it. Read Summary and Savings first. The remaining sheets exist so a number you intend to act on can be checked.
Savings sheet
Every reclaimable line, priced, split by how confident and how soon.
| Column | Example |
|---|---|
| Bucket | Disabled accounts still licensed |
| SKU | SPE_E3 |
| Seats | 34 |
| Confidence | Confirmed |
| Can be reduced | Now (monthly billing) |
| Renewal | 2027-02-01 |
| Action | Remove the licence. Convert the mailbox to shared first if the data is still needed. |
Users to investigate sheet
Per-user detail behind the counts.
| Column | Example |
|---|---|
| User | j.olsen@contoso.com |
| Name | Jonas Olsen |
| Enabled | Yes |
| Created | 2019-06-11 |
| SKUs | SPE_E3 |
| Verdict | Idle - investigate |
| Confidence | High |
Cannot be measured sheet
Accounts the evidence does not cover, kept out of the totals rather than assumed idle.
What you need
- A Microsoft 365 sign-in that can be granted these read scopes: Organization.Read.All and Directory.Read.All for subscriptions and SKUs, User.Read.All for who holds what, Reports.Read.All for per-workload usage, and AuditLog.Read.All for sign-in activity.
- Every one of those is read only. Consent is usually a Global Administrator's to give.
- If your tenant conceals user names in usage reports, per-user idle detection cannot run. The report says so rather than reporting everyone as idle.
What it will not do
- It never removes a licence, and it has no button that does. Reclaiming is done in the Microsoft 365 admin centre by you.
- Idle is not the same as unnecessary. A licence can be legitimately dormant, and the workbook keeps a Holds & safe reclaim sheet for exactly that reason.
- Microsoft's usage reports lag by a couple of days. The Summary sheet states the date the activity data was current as of.