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.

6 thoughts on “Bulk disable specific services via the Azure AD PowerShell module

  1. Troy says:

    What about perviously disabled Services/Products from the same SKU? If we already have Yammer disabled and then we use this script to disable Flow will this scrip account for that?

    Reply
    1. Vasil Michev says:

      It will only change the status of services you’ve explicitly listed in the $plansToDisable variable. If Yammer was already disabled, it will stay disabled.

      Reply
  2. Mark says:

    Helpful, but what now if we want to re-enable for all users already licensed (and skip those that have had Teams enabled?)

    Is that possible by tweaking this script?

    Reply
    1. Vasil Michev says:

      Not sure if I understand your exact scenario, but so far I haven’t run into a licensing situation that isn’t fixable via a bit of PowerShell magic 🙂

      Reply

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.