Even when using PowerShell, Microsoft doesn’t make it simple when it comes to adjusting licensing in bulk and service plan options/apps within. Mainly that is because there is no easy way to keep a current configuration – any license change you apply to a user overwrites their existing setup. To address that letdown I created a script you can find below.
I tried to make this script very flexible and user friendly, please see the highlights of the script:
- the script is interactive – just select all actions;
- no need to predefine any variables;
- works with all license packages;
- allows both enabling and disabling services/apps;
- respects the currents configuration for each user.
This script assumes you are already connected to the right services and have all modules installed.
# List License Packages
$LicensePackageChoices = @()
$i = 0
$LicensePackages = Get-MsolAccountSku
ForEach ($LicensePackage in $LicensePackages) {
$outObject = "" | Select Number,'Package Name','PackageID'
$i = $i + 1
$outObject."Number" = $i
$outObject.'Package Name' = $LicensePackage.SkuPartNumber
$outObject.PackageID = $LicensePackage.AccountSkuId
$LicensePackageChoices += $outObject
}
Write-host `n"Listing License Packages:" -ForegroundColor Cyan
$LicensePackageChoices | ft Number,'Package Name' | Out-Host
# Select License Package
Do {
Try {
$Num = $true
[int]$SelectedInput = Read-host "By typing a number, select a License Package you would like to adjust for each user that has it"
}
Catch {$Num = $false}
}
Until (($SelectedInput -gt 0 -and $SelectedInput -le $LicensePackageChoices.count) -and $Num -eq $true)
$SelectedLicensePackage = $LicensePackages[[int]$SelectedInput - 1]
$SelectedLicensePackage | Out-Host
# List all licenses users with selected License Package
Write-host "Lisiting all licensed users that have $($SelectedLicensePackage.SkuPartNumber):" -ForegroundColor Cyan
$Users = Get-MsolUser -All | Where-Object {($_.isLicensed -eq $true) -and ($_.Licenses.AccountSkuId -contains $SelectedLicensePackage.AccountSkuId)}
$Users | Select-Object DisplayName,UserPrincipalName,@{Label="Currently disabled within $($SelectedLicensePackage.SkuPartNumber)";Expression={(($_.Licenses | Where-Object {$_.AccountSkuId -eq $SelectedLicensePackage.AccountSkuId}).ServiceStatus | Where-Object {$_.ProvisioningStatus -eq 'Disabled'}).ServicePlan.ServiceName -join ','}} | ft
Write-host "Total - $($Users.Count)"`n -ForegroundColor Cyan
# Select between enabling or disabling a Service Plan
$AnswerEnableOrDisableService = Read-Host "Would you like to enable or disable a service within $($SelectedLicensePackage.SkuPartNumber) for every user that has it (type 'enable' or 'disable')?"
While ("enable","disable" -notcontains $AnswerEnableOrDisableService) {
$AnswerEnableOrDisableService = Read-Host "Would you like to enable or disable a service within $($SelectedLicensePackage.SkuPartNumber) for every user that has it (type 'enable' or 'disable')?"
}
# List Service Plans
$ServiceChoices = @()
$i = 0
$Services = (Get-MsolAccountSku | Where-Object {$_.AccountSkuId -eq $SelectedLicensePackage.AccountSkuId}).ServiceStatus
ForEach ($Service in $Services) {
$outObject = "" | Select Number,'Service Plan'
$i = $i + 1
$outObject."Number" = $i
$outObject.'Service Plan' = $Service.ServicePlan.ServiceName
$ServiceChoices += $outObject
}
Write-host `n"Listing Service Plans for $($SelectedLicensePackage.SkuPartNumber):" -ForegroundColor Cyan
$ServiceChoices | ft Number,'Service Plan' | Out-Host
# Select Service Plan
Do {
Try {
$Num = $true
[int]$SelectedInput = Read-host "By typing a number, select a Service Plan you would like to $($AnswerEnableOrDisableService) for each user that has $($SelectedLicensePackage.SkuPartNumber)"
}
Catch {$Num = $false}
}
Until (($SelectedInput -gt 0 -and $SelectedInput -le $ServiceChoices.count) -and $Num -eq $true)
$SelectedServicePlan = $Services[[int]$SelectedInput - 1]
$SelectedServicePlan | select-object $_.ServicePlan.ServiceName | Out-Host
# Run for each user
foreach ($User in $Users) {
[Array]$AlreadyDisabledServicePlans = (($User.Licenses | Where-Object {$_.AccountSkuId -eq $SelectedLicensePackage.AccountSkuId}).ServiceStatus | Where-Object {$_.ProvisioningStatus -eq 'Disabled'}).ServicePlan.ServiceName
# Update Service Plans if 'disable'
If ($AnswerEnableOrDisableService -eq 'disable') {
[Array]$DisablePlans = $AlreadyDisabledServicePlans + $SelectedServicePlan.ServicePlan.ServiceName
$DisablePlans = $DisablePlans | Select-Object -Unique
$LicenseOption = New-MsolLicenseOptions -AccountSkuId $SelectedLicensePackage.AccountSkuId -DisabledPlans $DisablePlans
Set-MsolUserLicense -UserPrincipalName $User.UserPrincipalName -LicenseOptions $LicenseOption
}
# Update Service Plans if 'enable'
ElseIf ($AnswerEnableOrDisableService -eq 'enable') {
[Array]$DisablePlans = $AlreadyDisabledServicePlans
$DisablePlans = $DisablePlans | Where-Object {$_ -ne $SelectedServicePlan.ServicePlan.ServiceName}
$DisablePlans = $DisablePlans | Select-Object -Unique
If ($DisablePlans.Count -eq 0) {
$LicenseOption = New-MsolLicenseOptions -AccountSkuId $SelectedLicensePackage.AccountSkuId
}
Else {
$LicenseOption = New-MsolLicenseOptions -AccountSkuId $SelectedLicensePackage.AccountSkuId -DisabledPlans $DisablePlans
}
Set-MsolUserLicense -UserPrincipalName $User.UserPrincipalName -LicenseOptions $LicenseOption
}
# Output before and after change
$outObject = new-object psobject -Property @{
User = $User.DisplayName
'Already Disabled' = ($AlreadyDisabledServicePlans -join ",")
'Disabled Services after Update' = ($DisablePlans -join ",")
}
$outObject | Select-Object User,'Already Disabled','Disabled Services after Update'
}
Pingback: PowerShell - Office 365 - Disable an entire license package for each user - Office 365 Basics
Insane.
Insane indeed that Microsoft makes it hard to adjust.
“You have exceeded the maximum number of allowable transactions.”
Screw (edited by Paul) it.