Bulk disable specific services via the Azure AD PowerShell module

When it comes to bulk operations for Office 365 licenses, for years I have been recommending the approach used by Tino Donderwinkel, a Microsoft PFE. You can find a sample script over at his blog, and the reason why I’m recommending is the way it handles any individually enabled/disabled services in a given SKU. Now, with the advent of the Azure AD module and the recent announcement regarding Teams licensing, we took on the task of disabling Teams for all users in the company via Azure AD PowerShell.

To do so, we need to know few pieces of information. First of all, the cmdlet to use, namely Set-AzureADUserLicense. The cmdlet takes the ObjectId or the UserPrincipalName of the user as input, and also requires you to specify the information about any licenses via a specially prepared license variable. In this scenario, we will not be adding or removing any licenses but simply toggling the Teams plan for each license the user is currently assigned. Which means we also need to know the identifier of the Teams plan. Luckily, this identifier is the same across all tenants,  and is represented via the “57ff2da0-773e-42df-b2af-ffb7a2317929” GUID.

If we want to do this against all users, we will of course need to get the list of users first and then iterate over each of them. Yet another loop is needed to iterate over all of the licenses assigned for specific user. Since not all of the assigned SKUs for each user will have a matching Teams plan, we must also perform a check and simply skip any non-matching SKUs. If the SKU does have the Teams plan, the corresponding flag is toggled and the new licensing variable updated. Lastly, after all the licenses have been covered, the Set-AzureADUserLicense cmdlet is invoked to update the licensing information for that user.

Of course, disabling just the Teams plan is a corner case, more generic scenario will be to disable any plan, or set of plans and in order to enable this, we’ve made sure that the script also accepts multiple values for the $plansToDisable variable. In addition, because not every human thinks like a programmer and loves dealing with GUIDs, a simple “translation” can be added to the script to make sure we can use values such as “TEAMS1” or “EXCHANGE_S_ENTERPRISE” to designate the corresponding plans. Here’s how a sample script might look like:

Connect-AzureAD

$users = Get-AzureADUser -All:$true | ? {$_.AssignedLicenses}
$SKUs = Get-AzureADSubscribedSku

$plansToDisable = @("57ff2da0-773e-42df-b2af-ffb7a2317929","EXCHANGE_S_ENTERPRISE")

foreach ($user in $users) {
    $userLicenses = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicenses
    foreach ($license in $user.AssignedLicenses) {
        $SKU =  $SKUs | ? {$_.SkuId -eq $license.SkuId}
        foreach ($planToDisable in $plansToDisable) {
            if ($planToDisable -notmatch "^[{(]?[0-9A-F]{8}[-]?([0-9A-F]{4}[-]?){3}[0-9A-F]{12}[)}]?$") { $planToDisable = ($SKU.ServicePlans | ? {$_.ServicePlanName -eq "$planToDisable"}).ServicePlanId }
            if ($planToDisable -in $SKU.ServicePlans.ServicePlanId) {
                $license.DisabledPlans = ($license.DisabledPlans + $planToDisable | sort -Unique)
                Write-Host "Removed plan $planToDisable from license $($license.SkuId)"
            }
        }
        $userLicenses.AddLicenses += $license
    }
    Set-AzureADUserLicense -ObjectId $user.ObjectId -AssignedLicenses $userLicenses
}

While I have tested the script for every scenario I could think of, including groups of users with mixed licensed and users with more than one license assigned, it’s not unlikely that I might have missed some cases. In other words, make sure to test this script before running it in production. And let me know if you have any feedback.

This entry was posted in Azure AD, Office 365, PowerShell. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *