Ask for a Microsoft 365 license usage report and you can mean two different things. One is how many licenses you bought against how many are assigned. The other is whether the people holding them actually use the services. Microsoft answers each in a different place, in the admin center and in Microsoft Graph, but no single report joins the two, and none of them says what the unused part costs. Here is how to pull each one, how to unhide the user names Microsoft conceals by default, and what the reports leave out.
Sentsai’s free, read-only scan reads your licenses, users and sign-in activity together and flags paid licenses nobody holds, licenses on disabled accounts, idle and never-used accounts, and add-ons your suite already includes. The free scan shows the savings total; the itemized report is paid.
Needs a one-time approval of read-only access from an administrator who can approve apps. Not an admin? Email this to yours.
In the Microsoft 365 admin center, go to Billing, then Licenses. Each product shows how many licenses you have and how many are assigned. The page can add up every subscription with the same product name into one total, so two Business Premium subscriptions show as one combined number. Billing, then Your products shows one row per subscription, which is what you need to know which subscription a spare license belongs to and when it renews.
The same numbers are in Microsoft Graph. Get-MgSubscribedSku returns every SKU in the tenant with prepaidUnits, whose enabled value is the licenses in active subscriptions, and consumedUnits, the licenses assigned. Units counted as warning or suspended belong to subscriptions that have expired or been canceled, so leave them out of the spare count. The least privileged permission for this call is LicenseAssignment.Read.All.
Connect-MgGraph -Scopes "LicenseAssignment.Read.All", "Reports.Read.All"
Get-MgSubscribedSku -All | Select-Object SkuPartNumber, @{n="Purchased"; e={$_.PrepaidUnits.Enabled}}, ConsumedUnits, @{n="Spare"; e={$_.PrepaidUnits.Enabled - $_.ConsumedUnits}}
SkuPartNumber is the internal product code, such as SPE_E5 for Microsoft 365 E5. Microsoft publishes the mapping from codes to product names, with every service plan each product contains, in its Product names and service plan identifiers for licensing reference.
Go to Reports, then Usage. Under Microsoft 365 apps, the Active users tab lists every user with a last active date for Exchange, OneDrive, SharePoint, Viva Engage and Teams, whether each of those licenses is assigned, and when it was assigned. Pick the 7, 30, 90 or 180 day window and select Export for a CSV of the whole table. The data usually covers up to the last 24 to 48 hours. To open the reports you need an admin role such as Reports Reader; the Usage Summary Reports Reader role sees totals but no user details.
Other reports under Usage answer narrower questions: Mailbox usage for storage, Office activations for who has activated the desktop apps, and separate activity reports for Teams, OneDrive and SharePoint. For a licensing review, Active users is the one to start with.
Each admin center usage report has a Graph equivalent under /reports. The one behind the Active users page is getOffice365ActiveUserDetail. It takes a period of D7, D30, D90 or D180, or a single date within the last 30 days, and answers with a 302 redirect to a short-lived download URL for a CSV file. The columns include Has Exchange License and Exchange Last Activity Date, the same pair for OneDrive, SharePoint, Skype for Business, Yammer and Teams, each license assign date, and Assigned Products.
GET https://graph.microsoft.com/v1.0/reports/getOffice365ActiveUserDetail(period='D90')
Get-MgReportOffice365ActiveUserDetail -Period D90 -OutFile .\active-users-90d.csv
The permission is Reports.Read.All. When you run it as yourself rather than as an app, Microsoft also requires your account to hold an admin role such as Reports Reader, Exchange Administrator or SharePoint Administrator. Global Reader and Usage Summary Reports Reader get tenant-level totals only, without the per-user detail you need here.
If your export shows long strings of letters and numbers where names should be, that is the privacy setting, not a fault. By default, Microsoft 365 reports hide usernames, display names, group names and site URLs. A Global Administrator can show them: Settings, Org settings, the Services tab, Reports, then clear Conceal user, group, and site names in all reports and save. The change takes a few minutes and also applies to the Graph reports API, the Power BI usage analytics and the Teams admin center reports. Microsoft records it in the Purview audit log, and your privacy policy may require concealment, so agree it with whoever owns that policy first.
The same switch is exposed in Microsoft Graph as displayConcealedNames on /admin/reportSettings. Setting it to false shows names, and it needs the ReportSettings.ReadWrite.All permission:
Update-MgAdminReportSetting -BodyParameter @{ displayConcealedNames = $false }
Usage reports are built to show adoption, not to audit licensing, and the gaps matter:
Sentsai does this join for Microsoft 365, read-only, in minutes. It reads your subscribed SKUs for paid licenses nobody holds, the user list for disabled accounts still holding them, sign-in activity for dormant and never-used accounts, and each user’s service plans for add-ons a suite already includes, then estimates what each finding costs per year. The free scan shows the total annual savings it identified, how many users it checked and how many compliance gaps it found. The itemized list, with every named account and license, costs 5% of the identified annual savings, with a $99 minimum. Nothing in your tenant is changed.
Read-only, for Microsoft 365, in minutes. The free scan shows the total annual savings and the headline counts; the itemized, named list costs 5% of identified annual savings, $99 minimum.
Needs a one-time approval of read-only access from an administrator who can approve apps. Not an admin? Email this to yours.
Questions? support@sentsai.com