Bulk License Management in Microsoft 365 with PowerShell

Managing licenses one user at a time in the Microsoft 365 admin center is fine for a few users, but when you need to add licenses to 50 employees or remove licenses from terminated contractors, PowerShell is your friend.

TL;DR

  • Connect: Install-Module MSOnline; Connect-MsolService
  • Add licenses: Set-MsolUserLicense -AddLicenses
  • Remove licenses: Set-MsolUserLicense -RemoveLicenses
  • Bulk operations: Use CSV files and ForEach loops
  • Check usage: Get-MsolAccountSku for license availability
  • Best practice: Test with -WhatIf first

Connect to Microsoft 365

First, you need the MSOnline module:

# Install if needed
Install-Module MSOnline

# Connect
Connect-MsolService

This opens a browser window for authentication. Use a global admin account.

Check Available Licenses

Before assigning licenses, know what you have:

Get-MsolAccountSku

This shows:

AccountSkuId                           ActiveUnits WarningUnits ConsumedUnits
------------                           ----------- ------------ -------------
contoso:O365_BUSINESS_PREMIUM         100         0            87

The AccountSkuId is what you'll use in commands. For contoso, it would be "contoso:O365_BUSINESS_PREMIUM".

Add Licenses to Individual Users

Set-MsolUserLicense -UserPrincipalName "[email protected]" -AddLicenses "contoso:O365_BUSINESS_PREMIUM"

To add multiple licenses:

Set-MsolUserLicense -UserPrincipalName "[email protected]" -AddLicenses "contoso:O365_BUSINESS_PREMIUM","contoso:WINDOWS_STORE"

Remove Licenses from Users

Set-MsolUserLicense -UserPrincipalName "[email protected]" -RemoveLicenses "contoso:O365_BUSINESS_PREMIUM"

This removes the license but keeps the user account. If you want to remove all licenses:

$user = Get-MsolUser -UserPrincipalName "[email protected]"
$user.Licenses | ForEach-Object {Set-MsolUserLicense -UserPrincipalName $user.UserPrincipalName -RemoveLicenses $_.AccountSkuId}

Bulk License Operations

Create a CSV file with columns: UserPrincipalName, Action, LicenseSkuId

UserPrincipalName,Action,LicenseSkuId
[email protected],Add,contoso:O365_BUSINESS_PREMIUM
[email protected],Remove,contoso:O365_BUSINESS_PREMIUM
[email protected],Add,contoso:ENTERPRISEPACK

Then run:

$users = Import-Csv "C:\Temp\LicenseChanges.csv"

foreach ($user in $users) {
    if ($user.Action -eq "Add") {
        Set-MsolUserLicense -UserPrincipalName $user.UserPrincipalName -AddLicenses $user.LicenseSkuId
        Write-Host "Added license $($user.LicenseSkuId) to $($user.UserPrincipalName)"
    }
    elseif ($user.Action -eq "Remove") {
        Set-MsolUserLicense -UserPrincipalName $user.UserPrincipalName -RemoveLicenses $user.LicenseSkuId
        Write-Host "Removed license $($user.LicenseSkuId) from $($user.UserPrincipalName)"
    }
}

Replace Licenses (Upgrade/Downgrade)

To change from one license to another:

Set-MsolUserLicense -UserPrincipalName "[email protected]" -RemoveLicenses "contoso:O365_BUSINESS_PREMIUM" -AddLicenses "contoso:ENTERPRISEPACK"

This removes the old license and adds the new one in one command.

Check User License Status

Get-MsolUser -UserPrincipalName "[email protected]" | Select-Object DisplayName, Licenses

This shows what licenses the user has assigned.

Bulk Operations by Department/Group

Add licenses to all users in a department:

Get-MsolUser -All | Where-Object {$_.Department -eq "Sales"} | ForEach-Object {
    Set-MsolUserLicense -UserPrincipalName $_.UserPrincipalName -AddLicenses "contoso:O365_BUSINESS_PREMIUM"
}

License Reporting

Get a report of all licensed users:

Get-MsolUser -All | Where-Object {$_.isLicensed -eq $true} | Select-Object DisplayName, UserPrincipalName, Licenses | Export-Csv "C:\Temp\LicensedUsers.csv" -NoTypeInformation

Count licenses by type:

Get-MsolUser -All | Where-Object {$_.isLicensed -eq $true} | ForEach-Object {
    $_.Licenses | ForEach-Object {
        $_.AccountSkuId
    }
} | Group-Object | Sort-Object Count -Descending

Common Issues and Solutions

Error: "The license assignment failed"

  • Check if you have enough licenses available
  • Verify the AccountSkuId is correct
  • Make sure the user exists and isn't blocked

Error: "You cannot remove the last license from a user"

  • Users must have at least one license to remain active
  • If you want to deactivate a user, use Set-MsolUser -BlockCredential $true instead

Licenses not applying immediately

  • Changes can take 5-15 minutes to propagate
  • User may need to sign out and back in to Office apps
  • Check the user's license status with Get-MsolUser

Best Practices

  • Use -WhatIf first: Add -WhatIf to any Set-MsolUserLicense command to preview changes
  • Work in batches: Don't try to license 1000 users at once; do 50-100 at a time
  • Document changes: Keep a log of what licenses you assigned and when
  • Check license usage: Monitor your license consumption regularly
  • Use service accounts: Don't use your personal admin account for bulk operations

Quick Reference

# Connect
Connect-MsolService

# Check available licenses
Get-MsolAccountSku

# Add license to user
Set-MsolUserLicense -UserPrincipalName "[email protected]" -AddLicenses "tenant:LICENSE_SKU"

# Remove license from user
Set-MsolUserLicense -UserPrincipalName "[email protected]" -RemoveLicenses "tenant:LICENSE_SKU"

# Check user licenses
Get-MsolUser -UserPrincipalName "[email protected]" | Select-Object DisplayName, Licenses

# Bulk from CSV
$users = Import-Csv "licenses.csv"
$users | ForEach-Object {Set-MsolUserLicense -UserPrincipalName $_.UserPrincipalName -AddLicenses $_.LicenseSkuId}

PowerShell license management saves hours when you have to make bulk changes. The admin center is fine for one-offs, but PowerShell is where the real efficiency lives.

Need Help with Microsoft 365 License Management?

License management, user provisioning, and Microsoft 365 administration can be complex. My company NHM Ohio provides comprehensive Microsoft 365 management services to keep your licensing efficient and cost-effective.

Whether you need license optimization, bulk user management, or ongoing administration, explore our Microsoft 365 services or contact us for assistance.