30-second answer

PowerShell
# Read-only. A SKU is a bundle; what a person can do is the plans inside it.
Connect-MgGraph -Scopes 'Organization.Read.All', 'User.Read.All' -NoWelcome
Get-MgSubscribedSku | Select-Object SkuPartNumber, AppliesTo

What a person can do is the service plans inside the bundle, minus the ones that assignment has disabled.

What this proves

Which capabilities an assignment delivers to a particular person, as the directory reports them. Not whether the person uses them, and not whether anything would break if the assignment changed.

What it does not prove

  • That a count of licences tells you anything about capability. Two people with the same SKU can hold different capabilities, because assignedLicenses carries a disabledPlans collection per assignment.
  • That every plan in a SKU is something a person has. appliesTo on a service plan is either User or Company: User - service plan can be assigned to individual users. Company - service plan can be assigned to the entire tenant.
  • That a plan listed is a plan working. provisioningStatus has six values. Microsoft describes PendingActivation as the service is provisioned but requires explicit activation by an administrator.
  • That every SKU can even be assigned. Only SKUs with target class User are assignable, and subscribedSku.appliesTo is what says which.

PowerShell

PowerShell
# All reads.

# What the tenant holds, and what each bundle contains.
$skus = Get-MgSubscribedSku -All

# What one person holds, including the plans switched off for them.
$person = Get-MgUser -UserId 'someone@contoso.com' -Property 'assignedLicenses'

# What that assignment actually delivers.
foreach ($held in $person.AssignedLicenses) {
    $sku = $skus | Where-Object { $_.SkuId -eq $held.SkuId }
    $sku.ServicePlans |
        Where-Object { $_.AppliesTo -eq 'User' } |
        Where-Object { $_.ProvisioningStatus -eq 'Success' } |
        Where-Object { $held.DisabledPlans -notcontains $_.ServicePlanId } |
        Select-Object ServicePlanName
}

Example output

Text
ServicePlanName
---------------
EXCHANGE_S_ENTERPRISE
SHAREPOINTENTERPRISE
TEAMS1

Three capabilities from one bundle that lists more. The rest were either switched off for this person, tenant-wide rather than personal, or not provisioned.

Explanation

The four fields, and what each decides

FieldWhat it decides
subscribedSku.appliesTowhether the SKU can be assigned to a person at all
servicePlans[].appliesTowhether a plan is a user capability or a tenant-wide one
servicePlans[].provisioningStatuswhether the plan is actually provisioned
assignedLicenses[].disabledPlanswhich plans are switched off for this person

disabledPlans holds service plan identifiers, and Microsoft says where they come from: IDs are available in servicePlans > servicePlanId in the tenant's subscribedSkus. The two reads have to be joined; neither answers on its own.

Two people with the same SKU are not the same

disabledPlans is a property of the assignment, not of the SKU. An administrator who gives everyone the same licence and switches off three plans for contractors has produced two capability sets from one licence name, and nothing in a SKU count shows it.

The same capability can arrive twice

Different SKUs can contain the same service plan, and standalone products overlap with suites by design. That produces two facts worth separating: a plan delivered by exactly one of a person's assignments would stop being delivered if that assignment were removed, and a plan delivered by more than one would not, because another assignment already carries it.

Why an overlap does not mean a licence can be removed

Finding that two assignments deliver the same plan establishes that the capability arrives twice. It does not establish that either assignment is unnecessary, because the directory does not show the quota or limit each SKU attaches to the plan, what an agreement requires the organisation to hold, which policies or workloads depend on the assignment, or whether the person uses the capability at all, which is a separate reading with its own limits.

This capability also arrives from somewhere else and this licence can be removed are different statements, and only the first is available here.

Production considerations

  • Read the SKUs and the assignments in one pass and join them on skuId. Reading either alone produces a picture that looks complete and is not.
  • Keep the SKUs one row each. Summing quantities across them produces a number that means something different on a paid seat and on a free or tenant-wide one.
  • Organization.Read.All reads the SKUs and User.Read.All reads the assignments. Both are read-only.

None. This capability arrives twice is an observation, and whether a licence may be removed is a conclusion that needs evidence this read does not carry.

References

Found something wrong? Suggest a correction. The article source is not public; the engine it cites is.

What this answer underwrites

The engine reads these Microsoft operations to collect evidence, so what is established here is what those collectors rest on.

  • licensingwhat is assigned in one tenant, and whether the usage reports are permitted to name the people who hold it