How Microsoft 365 Licenses Get Freed Up When Users Are Deleted and How to Reassign Them

Microsoft 365 administrators often face the challenge of optimizing license usage, especially in scenarios where users are deleted. Licenses assigned to a user are freed up immediately upon deletion, allowing these licenses to be reassigned to other unlicensed but active users in the tenant. To simplify this process, we’ve created a PowerShell script that automates the identification of unlicensed users and reassigns freed licenses efficiently.

The Script: Reassign Freed Licenses to Unlicensed Users


# Prerequisites:
# Ensure you have the Microsoft.Graph PowerShell module installed and connected.
# Connect-MgGraph -Scopes "User.ReadWrite.All", "Directory.ReadWrite.All"

# Specify the SKU ID of the license you want to reassign (use Get-MgSubscribedSku to fetch this info)
$LicenseSkuId = "ENTER_SKU_ID_HERE"  # Example: "yourtenant:STANDARDPACK"

# Fetch all users in the tenant
$allUsers = Get-MgUser -All -Filter "AccountEnabled eq true" -ConsistencyLevel eventual

# Filter unlicensed users
$unlicensedUsers = $allUsers | Where-Object {
    ($_.AssignedLicenses.Count -eq 0)  # No assigned licenses
}

# Display unlicensed users for confirmation
Write-Host "Unlicensed Users Found:" -ForegroundColor Yellow
$unlicensedUsers | ForEach-Object {
    Write-Host $_.DisplayName, $_.UserPrincipalName
}

# Confirm reassigning licenses
$confirmation = Read-Host "Do you want to assign licenses to the unlicensed users listed above? (yes/no)"

if ($confirmation -ne "yes") {
    Write-Host "Operation cancelled." -ForegroundColor Red
    return
}

# Assign licenses to unlicensed users
foreach ($user in $unlicensedUsers) {
    try {
        # Corrected the license assignment logic
        $AddLicenses = @(@{SkuId = $LicenseSkuId})
        $RemoveLicenses = @()
        Set-MgUserLicense -UserId $user.Id -AddLicenses $AddLicenses -RemoveLicenses $RemoveLicenses
        Write-Host "Successfully assigned license to $($user.DisplayName) ($($user.UserPrincipalName))" -ForegroundColor Green
    } catch {
        Write-Host "Failed to assign license to $($user.DisplayName) ($($user.UserPrincipalName)): $_" -ForegroundColor Red
    }
}

Write-Host "License reassignment completed." -ForegroundColor Cyan
                            

How Can You Get The SKU ID of the license you want to reassign?

By running the following cmdlet:

Get-MgSubscribedSku | Select-Object SkuPartNumber, SkuId, ConsumedUnits, PrepaidUnits

How the Script Works

  1. Connect to Microsoft Graph:
    Ensure you’ve installed the Microsoft Graph PowerShell module and connected to the tenant with the necessary permissions.
  2. Fetch All Active Users:
    The script retrieves all users with `AccountEnabled` set to `true`, filtering out inactive or deleted accounts.
  3. Identify Unlicensed Users:
    Users with no assigned licenses are filtered from the list.
  4. Confirm Action:
    The script lists all unlicensed users and prompts for confirmation before proceeding with license assignment.
  5. Assign Licenses:
    The script assigns the specified license SKU to each unlicensed user using the `Set-MgUserLicense` cmdlet.
  6. Error Handling:
    Any errors encountered during the process are logged for review, ensuring the script can continue with other users.

Further Enhancements

  1. Dynamic SKU Selection:
    Modify the script to dynamically fetch available licenses and prompt the administrator to select a license SKU.
  2. Automated Execution
    Schedule the script to run periodically using Task Scheduler or Azure Automation, ensuring unlicensed users are always assigned available licenses.
  3. Email Notifications:
    Add functionality to email a summary report of the reassigned licenses to stakeholders after execution.
  4. Detailed Reporting:
    Extend the script to generate a CSV report of all license assignments, including success and failure logs.

Possible Errors and Solutions

Error Cause Solution
"Cannot convert the literal 'System.Collections.Hashtable' to the expected type 'Edm.Guid'" Incorrect format for the -AddLicenses parameter. Use the correct format: @(@{SkuId = "<SkuId>"}).
Insufficient Permissions The required Graph API permissions (User.ReadWrite.All, Directory.ReadWrite.All) are not granted. Ensure the app has appropriate permissions in Azure AD and admin consent is provided.
License Exhausted No available licenses in the tenant. Check license availability using Get-MgSubscribedSku and acquire additional licenses if needed.

Conclusion

Efficient license management is vital for cost optimization in Microsoft 365. By automating the reassignment of freed licenses to unlicensed users, this script ensures optimal use of your organization’s resources. Implementing such tools reduces manual overhead and enables administrators to focus on strategic tasks. Try the script today and streamline your license management process!

© m365corner.com. All Rights Reserved. Design by HTML Codex