Removing the License for an Office 365 Feature with PowerShell

TeamsTenantSettings

Changing Licenses for Teams

As part of the transition to the Teams and Skype for Business Online Admin Center (TSBAC), Microsoft is changing the way tenants manage Teams licenses. Instead of turning Teams on or off for users and guests at a tenant level (Figure 1), Teams now uses the licenses assigned to individual users to control access.

Teams Licensing
Figure 1: The old way of assigning Teams licenses (image credit: Tony Redmond)

Removing a Teams License

By default, Teams is enabled for all users with a suitable license, such as Office 365 E3 or E5, so if you want to disable access to Teams, you must edit the account and remove the Teams licenses from the Product Licenses section (Figure 2).

Disable Teams for a user
Figure 2: Removing a Teams license from a user with the Office 365 Admin Center (image credit: Tony Redmond)

Moving a slider is OK for one user, gets boring after several users, and becomes a royal pain after a few more. Fortunately, you can use PowerShell to remove licenses for sub-features bundled into an Office 365 plan like Teams, Forms, To-Do, or Stream.

PowerShell License Management

Licenses are assigned to Azure Active Directory accounts, so the cmdlets to manage licenses are in the Azure Active Directory PowerShell module. Two versions of the module are in common use today. The example shown below uses V1; the exercise to upgrade the script to V2 is left for the reader.

Microsoft has a script to disable Teams licenses that you can check out too. I don’t like the script too much because it assumes that you’re going to disable the Teams license for all users with a certain plan, and that you only use one plan. One of the joys of Office 365 is that you can mix and match plans to meet your functional and financial requirements, so limiting things to a single plan seems like a bad thing.

Scripting License Removals

The script below depends on the Exchange Online and Microsoft Online Services (MSOL) PowerShell modules. You need to connect to both services. The script then does the following:

  • Sets up the Office 365 plans to check. “ENTERPRISEPACK” means Office 365 E3 while “ENTERPRISEPREMIUM” is Office 365 E5. The ENTERPRISEPREMIUM_NOPSTNCONF is a variant of Office 365. To see what licenses you use in your tenant, run the Get-MsolAccountSku cmdlet.
  • Creates a set of mailboxes to process. To mark the accounts to disable for Teams, I set the value of ExtensionCustomAttribute1 in their mailboxes to “NoTeams.” This attribute is filterable, which means that it’s fast to retrieve. There are 20 custom attributes to choose from, so it shouldn’t be a problem to find one to use.
  • For each mailbox, we examine the licenses assigned to the user to find if any are in the plans we want to process. If we find a plan, we remove the Teams feature from the plan and update the user account.
  • If we remove a license, we write some information back to the mailbox to allow admins to keep track of what happened.
$TenantName = "Tenant:"
$SKus = @{}
$Skus.Add("ENTERPRISEPACK","Tenant:ENTERPRISEPACK")
$Skus.Add("ENTERPRISEPREMIUM","Tenant:ENTERPRISEPREMIUM")
$Skus.Add("ENTERPRISEPREMIUM_NOPSTNCONF","Tenant:ENTERPRISEPREMIUM_NOPSTNCONF")

$MBX = (Get-Mailbox -RecipientTypeDetails UserMailbox -Filter {ExtensionCustomAttribute1 -eq "NoTeams"}| Select DisplayName, UserPrincipalName, Alias, ExternalDirectoryObjectId)
$LicensesRemoved = 0
ForEach ($M in $MBX) {
        Write-Host "Checking licenses for" $M.DisplayName
        $MsoUser = (Get-MsolUser -ObjectId $M.ExternalDirectoryObjectId)
        $i = 0   
        Foreach ($ms in $MsoUser.Licenses.Accountsku.Skupartnumber) {
        If ($Skus.ContainsKey($MsoUser.licenses[$i].Accountsku.Skupartnumber))
        {
            $FullLicense = $TenantName + $MsoUser.Licenses[$i].Accountsku.Skupartnumber
            $RemoveOption = (New-MsolLicenseOptions -AccountSkuId $FullLicense -DisabledPlans "TEAMS1")
            Set-MsolUserLicense -ObjectId $M.ExternalDirectoryObjectId -LicenseOptions $RemoveOption
            $LicenseUpdateMsg = "Teams license removed for " + $M.DisplayName + " on " + (Get-Date) + " from " + $FullLicense
            Set-Mailbox -Identity $M.Alias -ExtensionCustomAttribute2 $LicenseUpdateMsg
            Write-Host "Teams license removed from" $FullLicense "for" $M.DisplayName
            $LicensesRemoved++
        }
       $i++ }
}
Write-Host "Total Teams Licenses Removed:" $LicensesRemoved

To use the script in your test (or to test it first), replace the “Tenant” string with your tenant name. Feel free to customize the code to your heart’s content.

Removing Other Options from Plans

The same code will work to remove other options from Office 365 plans. To get a list of options in a plan, load the license information for a user:

$UserLicenses = Get-MsolUser -SearchString [email protected]

Now examine the licenses assigned to the user:

$UserLicenses.Licenses.Accountsku.Skupartnumber
ENTERPRISEPREMIUM
SMB_APPS
EMSPREMIUM
ENTERPRISEPREMIUM_NOPSTNCONF
POWER_BI_STANDARD

Pick the plan you want to examine. In this case, I’ll take the ENTERPRISEPREMIUM plan, so that reveals:

$UserLicenses.Licenses[0].Servicestatus

ServicePlan           ProvisioningStatus
-----------           ------------------
BPOS_S_TODO_3         Success
FORMS_PLAN_E5         Success
STREAM_O365_E5        Success
THREAT_INTELLIGENCE   Success
Deskless              Success
FLOW_O365_P3          Success
POWERAPPS_O365_P3     Success
TEAMS1                Success
EQUIVIO_ANALYTICS     Success
LOCKBOX_ENTERPRISE    Success
EXCHANGE_ANALYTICS    Success
SWAY                  Success
MCOEV                 Success
MCOMEETADV            Success
BI_AZURE_P2           Success
INTUNE_O365           PendingActivation
PROJECTWORKMANAGEMENT Success
RMS_S_ENTERPRISE      Success
YAMMER_ENTERPRISE     Success
OFFICESUBSCRIPTION    Success
MCOSTANDARD           Success
EXCHANGE_S_ENTERPRISE Success
SHAREPOINTENTERPRISE  Success
SHAREPOINTWAC         Success

To disable an option, replace the “TEAMS1” used in the script (for Teams) with the code for the option you want to process. For example, BPOS_S_TODO_3 is Microsoft To-Do, FORMS_PLAN_E5 is Microsoft Forms, and so on.

Controlling Guest Licenses

The setting controlling access for guest users is now in the Teams and Skype for Business Admin Center under org-wide settings (Figure 3). Or rather, it will be when Microsoft completes the transition. If you don’t see the setting now (it’s not in the screenshot), it will be soon. In the meantime, if you need to enable or disable Teams access for guests, use the Set-CSTeamsClientConfiguration cmdlet to update the AllowGuestUser setting to $True or $False as you wish.

Teams Guest Access policy
Figure 3: Settings to control guest access to Teams (image credit: Tony Redmond)

You can’t assign a license to an individual guest user because guest accounts don’t need to be licensed. What you can do is control the actions that guests can take, such as the ability to use personal chat.

If you need to block an individual guest account from Teams (for instance, because they belong to a competitor domain), you should remove the account from Azure Active Directory. Removing a guest account will also stop their access to Planner, Office 365 Groups, and any sharing granted to the account to SharePoint Online and OneDrive for Business documents.

Automating License Management Isn’t Hard

Despite what some ISVs say, automating the assignment and retraction of licenses to Office 365 users isn’t hard. You can use Azure Active Directory groups to manage licenses or roll your own code with PowerShell. Or, if you really must, do it the hard way through the Office 365 Admin Center. Your choice!

Follow Tony on Twitter @12Knocksinna.

Want to know more about how to manage Office 365? Find what you need to know in “Office 365 for IT Pros”, the most comprehensive eBook covering all aspects of Office 365. Available in PDF and EPUB formats (suitable for iBooks) or for Amazon Kindle.