License helpers
Backed by Microsoft Graph with a cached SKU catalog. For full details and examples, run Get-Help <FunctionName> -Detailed.
User-centric license cmdlets (Add/Get/Remove/Copy/Move-UserMsolAccountSku) support full UPNs/object IDs and short identifiers (for example alias/SamAccountName/UPN prefix) via the shared resolver.
Add-UserMsolAccountSku
Assign licenses by friendly name (resolved via catalog), SKU part number, or SKU ID to a user.
Syntax
Add-UserMsolAccountSku -UserPrincipalName <String> -License <String[]> [-ForceLicenseCatalogRefresh] [-ShowErrorDetails]
Add-UserMsolAccountSku <UserPrincipalName> -License <String[]> [-ForceLicenseCatalogRefresh] [-ShowErrorDetails]
| Parameter | Type | Description | Required | Default |
|---|---|---|---|---|
UserPrincipalName | String | Target user UPN, object ID, or short identifier. | Yes | - |
License | String[] | Friendly name, SKU part number, or SKU ID. Accepts multiple values. | Yes | - |
ForceLicenseCatalogRefresh | Switch | Redownload license catalog cache. | No | False |
ShowErrorDetails | Switch | Include exception details in error messages. | No | False |
Examples
Add-UserMsolAccountSku -UserPrincipalName 'user@contoso.com' -License 'Microsoft 365 E3'
Add-UserMsolAccountSku -UserPrincipalName 'user@contoso.com' -License 'ENTERPRISEPACK','VISIOCLIENT'
Add-UserMsolAccountSku -UserPrincipalName 'user@contoso.com' -License '18181a46-0d4e-45cd-891e-60aabd171b4e'
Add-UserMsolAccountSku 'user@contoso.com' -License 'Microsoft 365 Business Standard EEA (no Teams)'
'user1@contoso.com','user2@contoso.com' | Add-UserMsolAccountSku -License 'Microsoft 365 Business Standard EEA (no Teams)'
If the target user has no UsageLocation, Nebula.Core sets it automatically using the UsageLocation key from your configuration (default US, override via %USERPROFILE%\.NebulaCore\settings.psd1). If updating the usage location fails, license assignment stops.
If the tenant does not have units available for the requested license, the assignment is avoided and a warning message is displayed.
Copy-UserMsolAccountSku
Copy all licenses (with disabled plans preserved) from one user to another without removing them from the source.
Syntax
Copy-UserMsolAccountSku -SourceUserPrincipalName <String> -DestinationUserPrincipalName <String>
Copy-UserMsolAccountSku <SourceUserPrincipalName> <DestinationUserPrincipalName>
| Parameter | Type | Description | Required | Default |
|---|---|---|---|---|
SourceUserPrincipalName | String | Source user UPN, object ID, or short identifier. | Yes | - |
DestinationUserPrincipalName | String | Destination user UPN, object ID, or short identifier. | Yes | - |
Example
Copy-UserMsolAccountSku -SourceUserPrincipalName 'user1@contoso.com' -DestinationUserPrincipalName 'user2@contoso.com'
Copy-UserMsolAccountSku 'user1@contoso.com' 'user2@contoso.com'
Export-MsolAccountSku
Export all users with assigned licenses to CSV, mapping SKU part numbers to friendly names.
Syntax
Export-MsolAccountSku [-CsvFolder <String>] [-ForceLicenseCatalogRefresh]
| Parameter | Type | Description | Required | Default |
|---|---|---|---|---|
CsvFolder | String | Output folder. | No | Current directory |
ForceLicenseCatalogRefresh | Switch | Redownload the license catalog cache. | No | False |
Example
Export-MsolAccountSku -CsvFolder 'C:\Temp\Reports'
Get-TenantMsolAccountSku
List tenant SKUs with resolved names, totals, consumed, available (enabled minus consumed), and seat states (filter by name or SKU part number).
Syntax
Get-TenantMsolAccountSku [-ForceLicenseCatalogRefresh] [-Filter <String>] [-SampleUsers <Int32>] [-AsTable] [-GridView]
| Parameter | Type | Description | Required | Default |
|---|---|---|---|---|
ForceLicenseCatalogRefresh | Switch | Redownload license catalog cache. | No | False |
Filter | String | Show only licenses whose name or SkuPartNumber contains the provided text. | No | - |
SampleUsers | Int32 | Return up to N sample users per license (requires -Filter). Defaults to 5 when specified. | No | 5 |
AsTable | Switch | Format output as a table. | No | False |
GridView | Switch | Show output in a GridView window. | No | False |
Example
Get-TenantMsolAccountSku -AsTable
Get-TenantMsolAccountSku -Filter "E3" -AsTable
Get-TenantMsolAccountSku -Filter "E3" -SampleUsers
Available is calculated as Enabled - Consumed (never below zero). The Total column shows a friendly breakdown (Enabled/Suspended), while TotalCount remains the numeric total for scripting.
Need renewal/expiration or billing profile details? Open the Microsoft 365 Admin Center subscriptions page: https://admin.cloud.microsoft/?#/subscriptions
Get-UserMsolAccountSku
Show licenses assigned to a single user with friendly names.
Syntax
Get-UserMsolAccountSku -UserPrincipalName <String> [-Clipboard] [-CheckAvailability] [-ForceLicenseCatalogRefresh] [-ShowErrorDetails]
Get-UserMsolAccountSku <UserPrincipalName> [-Clipboard] [-CheckAvailability] [-ForceLicenseCatalogRefresh] [-ShowErrorDetails]
| Parameter | Type | Description | Required | Default |
|---|---|---|---|---|
UserPrincipalName | String | Target UPN, object ID, or short identifier. | Yes | - |
Clipboard | Switch | Copy the resolved license names (fallback: SkuPartNumber) to the clipboard as "License1","License2". | No | False |
CheckAvailability | Switch | Show tenant available seat counts for the assigned SKUs. | No | False |
ForceLicenseCatalogRefresh | Switch | Redownload license catalog cache. | No | False |
ShowErrorDetails | Switch | Include exception details in error messages. | No | False |
Example
Get-UserMsolAccountSku -UserPrincipalName 'user@contoso.com'
'user1@contoso.com','user2@contoso.com' | Get-UserMsolAccountSku
Get-UserMsolAccountSku -UserPrincipalName 'user@contoso.com' -Clipboard
Get-UserMsolAccountSku -UserPrincipalName 'user@contoso.com' -CheckAvailability
Move-UserMsolAccountSku
Move all licenses (with disabled plans preserved) from one user to another.
Syntax
Move-UserMsolAccountSku -SourceUserPrincipalName <String> -DestinationUserPrincipalName <String>
Move-UserMsolAccountSku <SourceUserPrincipalName> <DestinationUserPrincipalName>
| Parameter | Type | Description | Required | Default |
|---|---|---|---|---|
SourceUserPrincipalName | String | Source user UPN, object ID, or short identifier. | Yes | - |
DestinationUserPrincipalName | String | Destination user UPN, object ID, or short identifier. | Yes | - |
Example
Move-UserMsolAccountSku -SourceUserPrincipalName 'user1@contoso.com' -DestinationUserPrincipalName 'user2@contoso.com'
Move-UserMsolAccountSku 'user1@contoso.com' 'user2@contoso.com'
Remove-UserMsolAccountSku
Remove licenses from a user by friendly name (resolved via catalog), SKU part number, or SKU ID.
Syntax
Remove-UserMsolAccountSku -UserPrincipalName <String> -License <String[]> [-ForceLicenseCatalogRefresh] [-ShowErrorDetails]
Remove-UserMsolAccountSku <UserPrincipalName> -License <String[]> [-ForceLicenseCatalogRefresh] [-ShowErrorDetails]
'user1@contoso.com','user2@contoso.com' | Remove-UserMsolAccountSku -License <String[]> [-ForceLicenseCatalogRefresh] [-ShowErrorDetails]
| Parameter | Type | Description | Required | Default |
|---|---|---|---|---|
UserPrincipalName | String | Target user UPN, object ID, or short identifier. | Yes | - |
License | String[] | Friendly name, SKU part number, or SKU ID. Accepts multiple values. | Yes | - |
ForceLicenseCatalogRefresh | Switch | Redownload license catalog cache. | No | False |
ShowErrorDetails | Switch | Include exception details in error messages. | No | False |
Remove-UserMsolAccountSku -UserPrincipalName <String> -All [-ForceLicenseCatalogRefresh] [-ShowErrorDetails]
| Parameter | Type | Description | Required | Default |
|---|---|---|---|---|
UserPrincipalName | String | Target user UPN, object ID, or short identifier. | Yes | - |
All | Switch | Remove all assigned licenses. | Yes | - |
ForceLicenseCatalogRefresh | Switch | Redownload license catalog cache. | No | False |
ShowErrorDetails | Switch | Include exception details in error messages. | No | False |
Examples
Remove-UserMsolAccountSku -UserPrincipalName 'user@contoso.com' -License 'Microsoft 365 E3'
Remove-UserMsolAccountSku -UserPrincipalName 'user@contoso.com' -License 'ENTERPRISEPACK','VISIOCLIENT'
Remove-UserMsolAccountSku -UserPrincipalName 'user@contoso.com' -License '18181a46-0d4e-45cd-891e-60aabd171b4e'
Remove-UserMsolAccountSku 'user@contoso.com' -License 'Exchange Online (Plan 2)'
'user1@contoso.com','user2@contoso.com' | Remove-UserMsolAccountSku -License 'Exchange Online (Plan 1)'
Remove-UserMsolAccountSku -UserPrincipalName 'user@contoso.com' -All
Update-LicenseCatalog
Refresh the local license catalog cache (download SKU mappings).
Syntax
Update-LicenseCatalog [-Force]
| Parameter | Type | Description | Required | Default |
|---|---|---|---|---|
Force | Switch | Force a refresh even if cache exists. | No | False |
Example
Update-LicenseCatalog -Force
Questions and answers
Can I export licenses/mailboxes without Graph?
No. License functions and some statistics require Microsoft Graph for complete data. Ensure Connect-Nebula requested the right scopes.