Skip to content

/commands/microsoft-graph/set-mguserlicense

Set-MgUserLicense: assign or remove Microsoft 365 licenses with Microsoft Graph PowerShell

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash)updated
tool
Microsoft Graph PowerShell
versions
Microsoft.Graph.Users.Actions 2.x, Microsoft.Graph.Authentication 2.41.2
os
windows, linux, macos

Set-MgUserLicense replaces Set-MsolUserLicense and Set-AzureADUserLicense. It always takes both -AddLicenses and -RemoveLicenses; pass an empty array for the one you do not use:

powershell
Connect-MgGraph -Scopes "User.ReadWrite.All", "Organization.Read.All"

$sku = Get-MgSubscribedSku -All | Where-Object SkuPartNumber -eq 'SPE_E3'
Set-MgUserLicense -UserId anna@contoso.com -AddLicenses @{SkuId = $sku.SkuId} -RemoveLicenses @()

SkuPartNumber values (for example SPE_E3 for Microsoft 365 E3, ENTERPRISEPACK for Office 365 E3) are listed in Microsoft's "Product names and service plan identifiers for licensing". Organization.Read.All is needed for Get-MgSubscribedSku.

Module and permissions

The cmdlet lives in Microsoft.Graph.Users.Actions, not in Microsoft.Graph.Users, and calls POST /users/{id}/assignLicense. Find-MgGraphCommand shows this from the metadata in Microsoft.Graph.Authentication 2.41.2, without a connection:

powershell
Import-Module Microsoft.Graph.Authentication
$c = Find-MgGraphCommand -Command Set-MgUserLicense | Select-Object -First 1
'{0} {1} (module Microsoft.Graph.{2})' -f $c.Method, $c.URI, $c.Module
$c.Permissions | Where-Object { $_.Name -notlike 'AgentIdUser*' } | Sort-Object PermissionType, Name -Unique |
  ForEach-Object { '{0,-14} {1,-32} admin consent: {2}' -f $_.PermissionType, $_.Name, $_.IsAdmin }

Output

POST /users/{user-id}/assignLicense (module Microsoft.Graph.Users.Actions)
Application    Directory.ReadWrite.All          admin consent: True
Application    LicenseAssignment.ReadWrite.All  admin consent: True
Application    User.ReadWrite.All               admin consent: True
DelegatedWork  Directory.ReadWrite.All          admin consent: True
DelegatedWork  LicenseAssignment.ReadWrite.All  admin consent: False
DelegatedWork  User.ReadWrite.All               admin consent: True

Delegated sign-in also needs a role that can assign licenses, such as License Administrator or User Administrator.

Common tasks

TaskCommand
Remove a licenseSet-MgUserLicense -UserId USER -AddLicenses @() -RemoveLicenses @($sku.SkuId)
Swap licensesSet-MgUserLicense -UserId USER -AddLicenses @{SkuId = $new.SkuId} -RemoveLicenses @($old.SkuId)
Disable service plansSet-MgUserLicense -UserId USER -AddLicenses @{SkuId = $sku.SkuId; DisabledPlans = $planIds} -RemoveLicenses @()
Show a user's licensesGet-MgUserLicenseDetail -UserId USER | Select-Object SkuPartNumber
Free seatsGet-MgSubscribedSku | Select-Object SkuPartNumber, ConsumedUnits, @{n='Total'; e={$_.PrepaidUnits.Enabled}}

-RemoveLicenses takes SKU IDs (GUIDs), not hashtables. Disabled plans are service plan IDs from $sku.ServicePlans:

powershell
$planIds = $sku.ServicePlans | Where-Object ServicePlanName -in 'MFA_PREMIUM','INTUNE_A' | Select-Object -ExpandProperty ServicePlanId

Errors you may see

  • A usage location error: the user has no UsageLocation (Graph requires it for users who are assigned licenses). Set it first with Update-MgUser -UserId USER -UsageLocation US.
  • Insufficient privileges to complete the operation.: missing scope or role (details).
  • The term 'Set-MgUserLicense' is not recognized: install the module with Install-Module Microsoft.Graph.Users.Actions -Scope CurrentUser (or the full Microsoft.Graph).

Sources