To find unlicensed users in Microsoft 365, list the enabled member accounts whose assigned licences are empty. The filter is an advanced query, so it needs the consistency level eventual and a count. Expect accounts that need no licence, such as the user accounts behind shared mailboxes, alongside people who were never given one.
| Method | Best fit |
|---|---|
| PowerShell | A CSV of enabled members with no licence, with any licence assignment errors counted. |
| Admin centre | A quick look with the standard Unlicensed users view, which saves nothing. |
| Altivane | Recommended for regular licence reviews, with failed assignments kept apart from accounts nobody licensed. |
Before you start
Use an account that can read users, such as Global Reader or Directory Readers. The PowerShell example requests User., the permission Microsoft gives for reading users' licence details; your organisation may require administrator consent.
Know what the list holds. The examples keep enabled member accounts, so guests and disabled accounts are left out. An advanced query reads an index that can lag by a little, so an account licensed a moment ago may still appear. The examples read and export, and change no account or licence; the admin centre's standard view saves nothing.
Option 1
Find unlicensed users with PowerShell
Install the modules once, then connect and export every enabled member with no licence. Microsoft Graph applies the filter, so only those accounts come back.
# Install once, if the modules are not already installed.
Install-Module Microsoft.Graph.Authentication, Microsoft.Graph.Users -Scope CurrentUser$ErrorActionPreference = 'Stop'
Connect-MgGraph -Scopes 'User.Read.All' -NoWelcome
try {
$query = @{
Filter = "assignedLicenses/`$count eq 0 and accountEnabled eq true" +
" and userType eq 'Member'"
Property = 'displayName,userPrincipalName,createdDateTime,licenseAssignmentStates'
ConsistencyLevel = 'eventual'
CountVariable = 'unlicensedCount'
}
$users = Get-MgUser -All @query
$report = @(foreach ($user in $users) {
$errors = @($user.LicenseAssignmentStates | Where-Object {
$_.Error -and $_.Error -ne 'None'
})
[pscustomobject]@{
DisplayName = $user.DisplayName
UserPrincipalName = $user.UserPrincipalName
Created = $user.CreatedDateTime
LicenceErrors = $errors.Count
}
})
if ($report.Count -eq 0) {
Write-Output 'Every enabled member account has a licence.'
} else {
$report | Sort-Object DisplayName |
Export-Csv -Path './unlicensed-users.csv' -NoTypeInformation -Encoding utf8
Write-Output "$($report.Count) enabled members have no licence."
}
} finally {
Disconnect-MgGraph | Out-Null
}Keep ConsistencyLevel and CountVariable: the filter needs them, or Microsoft Graph returns an error. The backtick before $count stops PowerShell reading it as a variable. LicenceErrors counts the licences recorded against the account with an error, such as a group's licence that couldn't be assigned. To include guests or disabled accounts, remove their part of the filter.
Check a single account
Reconnect with Connect-MgGraph, then list 1 person's licences. An empty result means none is assigned.
# Run while connected to Microsoft Graph. Replace the example account.
Get-MgUserLicenseDetail -UserId 'person@example.com' | Select-Object SkuPartNumberOption 2
Find unlicensed users in the admin centre
- Sign in to the Microsoft 365 admin centre for the correct tenant.
- Go to Users > Active users.
- Select Filter set and choose Unlicensed users, 1 of the standard views.
- Select a person and open the Licenses and Apps tab to confirm, then close the pane without changes.
The view lists every account with no licence, and its results can include users who have an Exchange mailbox but no licence. With more than 2,000 users, a standard view may be unsorted, so use the search box to find someone. It suits a quick look; for a file you can compare each month, use PowerShell or Altivane.
Option 3 ยท Recommended for regular licence reviews
Find unlicensed users with Altivane
- Open Altivane and choose the tenant.
- Run the Licensing scorecard report.
- Open the Excel workbook and find the Enabled Members Without sheet: each enabled member with no licence, with its status, last sign-in, when it was created, department and job title.
- Read Licence Assignment Errors for accounts whose licence failed to assign, with the product, whether it came directly or through a group, and the error.
Guests are left out, and an account whose licences all failed is listed with the errors rather than as unlicensed. Licence Summary counts enabled members without licences beside the licences purchased, assigned and available. The table goes to the workbook only to start; you can put it in the Word report too, up to 100 rows. Last Sign-In needs Microsoft Entra ID P1 or P2. The report needs a tenant signed in with a certificate.
Contact usCommon questions
Why are shared mailboxes on the list?
A shared mailbox has an associated user account, enabled by default with a password nobody knows. It needs no licence up to 50 GB, so its account is unlicensed by design. To watch the ones nearing that size, see how to find shared mailboxes near 50 GB in Exchange Online.
Why does the PowerShell call return an error?
The filter is an advanced query, so the request needs the consistency level eventual and a count. The script sets both; keep them if you adapt the call, and keep the backtick before $count inside double quotes.
Why is a disabled account without a licence missing?
The examples and Altivane keep enabled accounts only. Remove accountEnabled eq true from the script's filter to list disabled ones too.
Microsoft references
Technical references checked on 7 November 2026. The example scripts have been reviewed and syntax checked; they have not been run against a live tenant.