To list groups that assign licences in Microsoft 365, query Microsoft Graph for groups whose assigned licences aren't empty, then read each group's products and processing state. Only the group's direct members get the licences, because group-based licensing doesn't reach nested groups, and a licence that fails to assign is recorded on the member, not the group.
| Method | Best fit |
|---|---|
| PowerShell | A CSV of every licensing group with its products, members and members in error. |
| Admin centre | A look at the groups and users assigned 1 product, with its errors and issues. |
| Altivane | Recommended for regular licence reviews, with each group's users counted and failed assignments listed by account. |
Before you start
Use an account that can read groups and licences, such as Directory Readers or Global Reader. The PowerShell example requests Group. and LicenseAssignment., the least privileged permission Microsoft lists for reading the products; your organisation may require administrator consent.
Know what the list shows. Security groups, mail-enabled groups and Microsoft 365 groups can all assign licences. A large group, or a change to its members, can take a while to process, so a group's state may be queued or in progress. The examples read and export; they don't assign, remove or reprocess anything.
Option 1
List groups that assign licences with PowerShell
Install the modules once, then connect and export every group that assigns a licence. Microsoft Graph applies the filter, and the script counts each group's members and the members whose licence from it failed.
# Install once, if the modules are not already installed.
Install-Module Microsoft.Graph.Authentication, Microsoft.Graph.Groups -Scope CurrentUser
Install-Module Microsoft.Graph.Identity.DirectoryManagement -Scope CurrentUser
Install-Module Microsoft.Graph.Users -Scope CurrentUser$ErrorActionPreference = 'Stop'
Connect-MgGraph -Scopes 'Group.Read.All', 'LicenseAssignment.Read.All' -NoWelcome
try {
$names = @{}
foreach ($sku in Get-MgSubscribedSku -All) {
$names[$sku.SkuId.ToString()] = $sku.SkuPartNumber
}
$query = @{
Filter = 'assignedLicenses/$count ne 0'
Property = 'id,displayName,assignedLicenses,licenseProcessingState'
ConsistencyLevel = 'eventual'
CountVariable = 'groupCount'
}
$groups = @(Get-MgGroup -All @query | Sort-Object DisplayName)
if ($groups.Count -eq 0) {
Write-Output 'No group assigns licences.'
return
}
$report = @(foreach ($group in $groups) {
$products = @($group.AssignedLicenses | ForEach-Object {
$id = $_.SkuId.ToString()
if ($names.ContainsKey($id)) { $names[$id] } else { $id }
})
$errors = @(Get-MgGroupMemberWithLicenseError -GroupId $group.Id -All)
$members = Get-MgGroupMemberCount -GroupId $group.Id -ConsistencyLevel eventual
[pscustomobject]@{
Group = $group.DisplayName
Licences = $products -join '; '
ProcessingState = $group.LicenseProcessingState.State
Members = $members
MembersInError = $errors.Count
Id = $group.Id
}
})
$report | Export-Csv -Path './group-based-licensing.csv' -NoTypeInformation -Encoding utf8
$failing = @($report | Where-Object MembersInError -gt 0)
Write-Output "$($report.Count) groups assign licences; $($failing.Count) have members in error."
} finally {
Disconnect-MgGraph | Out-Null
}The CSV has 1 row per group: its products as part numbers, its processing state, how many direct members it has, how many of them hold a licence error from it, and its ID. ProcessingState is QueuedForProcessing, ProcessingInProgress or ProcessingComplete. Keep ConsistencyLevel and CountVariable: the filter needs them.
List the members in error for 1 group
Reconnect with Connect-MgGraph -Scopes 'Group., then list each member whose licence from 1 group couldn't be assigned, with the error.
# Run while connected to Microsoft Graph. Replace the example group ID.
$groupId = '00000000-0000-0000-0000-000000000000'
$failed = @(Get-MgGroupMemberWithLicenseError -GroupId $groupId -All)
foreach ($member in $failed) {
$user = Get-MgUser -UserId $member.Id -Property 'userPrincipalName,licenseAssignmentStates'
$user.LicenseAssignmentStates |
Where-Object { $_.AssignedByGroup -eq $groupId -and $_.Error -ne 'None' } |
Select-Object @{ Name = 'User'; Expression = { $user.UserPrincipalName } }, SkuId, Error
}The script keeps only the errors from that group, since a person can hold licences from other groups too. Error names the cause.
Option 2
Review licensed groups in the admin centre
- Sign in to the Microsoft 365 admin centre for the correct tenant.
- Go to Billing > Licenses and select a product.
- Read the list of assignments: a group that assigns the product appears by its name, beside the users assigned it directly.
- Select the Errors & issues tab for the users whose licence couldn't be assigned, and select a user to see why.
- To see a group's members, go to Teams & groups > Active teams & groups. Leave without choosing Unassign or Reprocess.
The admin centre works 1 product at a time, and its lists of users show 999 at a time. In the Microsoft Entra admin centre, Billing > Licenses > Overview shows a box when any group has licence errors. For every group and product in 1 file, use PowerShell or Altivane.
Option 3 ยท Recommended for regular licence reviews
List licensing groups with Altivane
- Open Altivane and choose the tenant.
- Run the Licensing scorecard report.
- Open the Excel workbook and find Group-Based Licensing: each group that assigns licences, with its products by name, its processing state and how many users hold a licence through it.
- Read Licence Assignment Errors for each user whose licence failed, with the group named under Assigned Via.
Licence Assignments, in the workbook only, lists every licensed user with each product and whether it's direct or group assigned. The report needs a tenant signed in with a certificate.
Contact usCommon questions
Why didn't a member of a nested group get the licence?
Group-based licensing doesn't support nested groups. When a group that holds a licence contains another group, only the users who are direct members of the first group are assigned it.
Why does a group have members in error?
The usual causes are too few licences left in the product, a service plan that conflicts with one the user already has, a usage location where the service isn't offered, and duplicate proxy addresses. If 1 product in a group fails, the group's other products may not be assigned either.
How do I see who holds licences directly?
Read each licensed user's assignment, which says whether it came from a group. See how to export Microsoft 365 licensed users.
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.
- Group-based licensing PowerShell examples
- Assign or unassign licences to a group in the Microsoft 365 admin centre
- Assign or unassign licences for users
- Get-MgGroup reference
- Get-
Mg Group Member With License Error reference - Get-MgGroupMemberCount reference
- group properties
- Advanced query capabilities on directory objects
- List subscribedSkus in Microsoft Graph