Find wasted Microsoft 365 licenses with PowerShell and Microsoft Graph
Most Microsoft 365 tenants pay for licenses nobody uses. The usual causes: Someone leaves, their account gets disabled , but the license stays assigned. An account is created for a hire or a project and never signed into . A user stops using the account, and it sits inactive for months. Each one keeps billing every month. Here's how to find them with Microsoft Graph PowerShell, read-only. What…
Microsoft 365 tenants often pay for licenses that remain unused due to various reasons such as employees leaving, accounts being disabled, or accounts created for temporary projects that are never utilized. To identify these wasted licenses, one must use Microsoft Graph PowerShell with read-only access. This requires PowerShell 7+, the Microsoft.Graph module, and an admin account with appropriate permissions.
The PowerShell script begins by connecting to Microsoft Graph with the necessary scopes, including User.Read.All, AuditLog.Read.All, and Organization.Read.All. The AuditLog.Read.All scope is crucial for retrieving sign-in activity data. Next, the script maps license IDs to their readable names using the Get-MgSubscribedSku cmdlet.
The script then retrieves all users, specifying the properties of interest such as IDs, display names, user principal names, account status, assigned licenses, sign-in activity, and creation date. To determine which users represent waste, the script establishes thresholds for inactivity (90 days) and a grace period for newly created accounts (30 days). Users are categorized as disabled but licensed, never signed in, or inactive for the specified duration.
The script also assigns approximate US list prices to different Microsoft 365 licenses, such as Business Premium ($22.00), Business Standard ($12.50), and Microsoft 365 E3 ($36.00). By summing the monthly costs of flagged licenses and multiplying by 12, the estimated annual waste can be calculated. For instance, in a test tenant with two disabled-but-licensed users, the waste amounts to $44.00 per month ($528.00 annually).
The complete script is freely available under the MIT license on GitHub and can be installed via the PowerShell Gallery. It exports results to a CSV file and offers customization options for thresholds and output preferences. The author encourages feedback on potential improvements and extensions for multi-tenant environments.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.