How to Remove a Single Service Plan from Multiple User Accounts with PowerShell

Remove Service Plan PowerShell to Manage User Functionality

Note: This post is now obsolete. Please see this article for an updated approach to the problem.

Service plans are non-saleable elements of a Microsoft licensable product (SKU or stock keeping unit). SKUs are what people often think of when they discuss licenses. Individual Microsoft 365 accounts can have multiple SKUs, such as TOPIC_EXPERIENCES, ENTERPRISEPACK, and EMSPREMIUM. The product names for these SKUs are Viva Topics, Office 365 E3, and Enterprise Mobility and Security E5. Product names appear in places like the Billing section of the Microsoft 365 admin center (Figure 1).

Product names in the Microsoft 365 admin center

Remove service plans PowerShell
Figure 1: Product Names in the Microsoft 365 admin center

At a more granular level, a “bundled” SKU like Office 365 E3 includes multiple service plans, each of which enable access to some functionality like an app. This page lays details the connections between SKUS and service plans.

At the time of writing, Office 365 E3 covers 28 service plans and Office 365 E5 has 53. Office 365 E5 includes service plans to license capabilities like advanced compliance features, customer lockbox, advanced auditing, content explorer, server-based auto-labeling for sensitivity labels and retention labels, records management, and information barriers.

Microsoft introduces new service plans to enhance its ability to license new features to different user communities or to provide control over user access to a new feature. Teams is a good example. The Teams service plan (TEAMS1) is in many Office 365 and Microsoft 365 SKUs. In April, Microsoft announced they would add the Teams Pro service plan to some SKUs and will use the Teams Pro service plan to allow accounts licensed with those SKUs to access new features. To date, Microsoft has not added the Teams Pro service plan to any SKU in my tenant nor have they described what features the new service plan will cover.

Reviewing Available Service Plans

In some cases, tenant administrators might not want users to be able to access a licensed app or capability. Perhaps the feature is obsolete, or the organization has different software to do the same thing, or maybe a delay is necessary to enable preparation of training, documentation, and support. Some years ago, Microsoft made a big thing about Kaizala and its impending integration into Teams. Kaizala is now an obsolete feature that’s still available in Office 365 E3 and E5. Sway is in the same category. Microsoft Bookings is an optional feature which isn’t often used by enterprise users, but it’s also part of Office 365 E3 and E5. In short, when you review the set of service plans bundled into Office 365 and Microsoft 365 SKUs, you might be surprised at the amount of unwanted debris in the mix.

Removing Individual Service Plans

Let’s say that we want to remove individual service plans from SKUs assigned to users. This post describes how to report the accounts assigned individual service plans (licenses) and explains how Azure AD stores the service plan information in user accounts. We want to go further by removing access to selected service plans, and as it turns out, we must use cmdlets from the older Microsoft Online Services module to get the job done. It’s possible to use the Set-AzureADUserLicense cmdlet to remove a service plan from an account. Laziness and the availability of some existing code to do the job stopped me using this cmdlet.

In any case, I wrote a script to demonstrate the principle of the steps to remove an individual service plan from multiple Microsoft 365 accounts. Three versions are available.

Given that Microsoft deprecated the licensing management cmdlets in the MSOL and Azure AD modules in 2023, it makes sense to focus on the version based on the Microsoft Graph PowerShell SDK.

The major steps to remove a service plan from Azure AD licenses with PowerShell are:

  • Determine the set of SKUs (products) available in the tenant.
  • Select the SKU to remove a service plan from. A tenant might use many SKUs, so we read the information with Get-AzureADSubscribedSKU (or Get-MgSubscribedSku) and ask the administrator to choose a SKU.
  • Select the service plan from the chosen SKU to remove. This is a matter of reading the service plans from the SKU and asking the administrator to choose one.
  • Select the target accounts. I use Get-ExoMailbox to fetch a set of user mailboxes because this cmdlet supports a wide range of server-side filters (for instance, everyone in a country or department). The important thing is that you fetch the Azure AD object identifiers for the target accounts. The Microsoft Graph PowerShell SDK version doesn’t use Exchange Online because it reads the licensed account information direct from Azure AD.
  • Access each account (using its object identifier) and remove the service plan. The MSOL version does this by running the Set-MsolUserLicense cmdlet. The Azure AD version uses the Set-AzureADUserLicense cmdlet, while the Graph SDK uses Set-MgUserLicense.
  • Report the service plans removed from SKUs assigned to the target mailboxes.

Figure 2 shows the MSOL version of the script in action. You can see the selection of the service domain, SKU, and service plan and processing of user accounts. In this case, the selected options remove the Sway service plan from the ENTERPRISEPACK (Office 365 E3) SKU.

Selecting the SWAY service plan to remove

Remove Azure AD license PowerShell
Figure 2: Running the script to remove the SWAY service plan from Office 365 E3 licenses assigned to Microsoft 365 users

The report output is a CSV file. Figure 3 shows the information captured in the report as viewed through the Out-GridView cmdlet.

Reporting the removal of a service plan

How to remove an Azure AD license with PowerShell
Figure 3: Reporting the removal of a service plan

PowerShell Scores Again

I’m sure others will have different ways to solve the problem of removing service plans from SKUs, which is just fine. What’s obvious here (once again) is that PowerShell is a very flexible tool for automating administrative operations. Which is why I am so surprised when tenant administrators admit that they have never taken the time to become acquainted with the basics of PowerShell scripting. It’s not difficult; there are tons of available examples to learn from; and it gets work done. All good stuff!


Learn more about how Office 365 really works on an ongoing basis by subscribing to the Office 365 for IT Pros eBook. Our monthly updates keep subscribers informed about what’s important across the Office 365 ecosystem.

9 Replies to “How to Remove a Single Service Plan from Multiple User Accounts with PowerShell”

  1. Every time I run your script – it returns ‘Total of 0 matching mailboxes found’ regardless of license or feature SKU selected.

  2. Every time I run your script – it returns ‘Total of 0 matching mailboxes found’ regardless of license or feature SKU selected. -> Same on my end. Output:
    Get-MgSubscribedSKU

    Id AccountId AccountName AppliesTo CapabilityStatus ConsumedUnits SkuId SkuPartNumber SubscriptionIds
    — ——— ———– ——— —————- ————- —– ————- —————
    47e211f4-33e3-42a4-b4a7-7eefea1ecc6f_4a51bf65-409c-4a91-b845-1121b571cc9d 47e211f4-33e3-42a4-b4a7-7eefea1ecc6f phoenixtestlab User Enabled 0 4a51bf65-409c-4a91-b845-1121b571cc9d FLOW_PER_USER {8a71a968-c1d8-47…
    47e211f4-33e3-42a4-b4a7-7eefea1ecc6f_6470687e-a428-4b7a-bef2-8a291ad947c9 47e211f4-33e3-42a4-b4a7-7eefea1ecc6f phoenixtestlab Company Enabled 0 6470687e-a428-4b7a-bef2-8a291ad947c9 WINDOWS_STORE {6a078885-5519-47…
    47e211f4-33e3-42a4-b4a7-7eefea1ecc6f_bf666882-9c9b-4b2e-aa2f-4789b0a52ba2 47e211f4-33e3-42a4-b4a7-7eefea1ecc6f phoenixtestlab User Enabled 1 bf666882-9c9b-4b2e-aa2f-4789b0a52ba2 POWERAPPS_PER_APP_IW {f4ccac71-3078-47…
    47e211f4-33e3-42a4-b4a7-7eefea1ecc6f_f30db892-07e9-47e9-837c-80727f46fd3d 47e211f4-33e3-42a4-b4a7-7eefea1ecc6f phoenixtestlab User Enabled 14 f30db892-07e9-47e9-837c-80727f46fd3d FLOW_FREE {04208c17-f520-4f…
    47e211f4-33e3-42a4-b4a7-7eefea1ecc6f_726a0894-2c77-4d65-99da-9775ef05aad1 47e211f4-33e3-42a4-b4a7-7eefea1ecc6f phoenixtestlab User Enabled 0 726a0894-2c77-4d65-99da-9775ef05aad1 MICROSOFT_BUSINESS_CENTER {576bd289-efe4-4e…
    47e211f4-33e3-42a4-b4a7-7eefea1ecc6f_606b54a9-78d8-4298-ad8b-df6ef4481c80 47e211f4-33e3-42a4-b4a7-7eefea1ecc6f phoenixtestlab User Enabled 1 606b54a9-78d8-4298-ad8b-df6ef4481c80 CCIBOTS_PRIVPREV_VIRAL {01c9d9be-66af-4b…
    47e211f4-33e3-42a4-b4a7-7eefea1ecc6f_dcb1a3ae-b33f-4487-846a-a640262fadf4 47e211f4-33e3-42a4-b4a7-7eefea1ecc6f phoenixtestlab User Enabled 6 dcb1a3ae-b33f-4487-846a-a640262fadf4 POWERAPPS_VIRAL {472960bb-b402-40…
    47e211f4-33e3-42a4-b4a7-7eefea1ecc6f_e0dfc8b9-9531-4ec8-94b4-9fec23b05fc8 47e211f4-33e3-42a4-b4a7-7eefea1ecc6f phoenixtestlab User Enabled 1 e0dfc8b9-9531-4ec8-94b4-9fec23b05fc8 Microsoft_Teams_Exploratory_Dept {75caabf1-cdb2-48…
    47e211f4-33e3-42a4-b4a7-7eefea1ecc6f_a403ebcc-fae0-4ca2-8c8c-7a907fd6c235 47e211f4-33e3-42a4-b4a7-7eefea1ecc6f phoenixtestlab User Enabled 13 a403ebcc-fae0-4ca2-8c8c-7a907fd6c235 POWER_BI_STANDARD {1e1fc1ee-94c9-4f…
    47e211f4-33e3-42a4-b4a7-7eefea1ecc6f_06ebc4ee-1bb5-47dd-8120-11324bc54e06 47e211f4-33e3-42a4-b4a7-7eefea1ecc6f phoenixtestlab User Enabled 5 06ebc4ee-1bb5-47dd-8120-11324bc54e06 SPE_E5 {bb6b2f4e-599c-4b…
    47e211f4-33e3-42a4-b4a7-7eefea1ecc6f_05e9a617-0261-4cee-bb44-138d3ef5d965 47e211f4-33e3-42a4-b4a7-7eefea1ecc6f phoenixtestlab User Enabled 24 05e9a617-0261-4cee-bb44-138d3ef5d965 SPE_E3 {5517238f-2854-4e…
    47e211f4-33e3-42a4-b4a7-7eefea1ecc6f_eda1941c-3c4f-4995-b5eb-e85a42175ab9 47e211f4-33e3-42a4-b4a7-7eefea1ecc6f phoenixtestlab User Enabled 1 eda1941c-3c4f-4995-b5eb-e85a42175ab9 POWERAUTOMATE_ATTENDED_RPA {30f4d888-2f5c-42.

    Two weeks ago, i’ve tested and works well.

    1. What version of the SDK are you using? I tested everything yesterday with V2.16 and it worked as expected. Are you using the script in https://github.com/12Knocksinna/Office365itpros/blob/master/RemoveServicePlan3.PS1.

      Given the “no matching mailboxes” error, I suspect that you’re using the version based on the AzureAD module https://github.com/12Knocksinna/Office365itpros/blob/master/RemoveServicePlan2.PS1. That module is now deprecated and probably doesn’t work. Also, the script included a filter to select a small number of mailboxes to test against that should be removed to match conditions in your tenant. Did you do that? (I have removed the filter in the version posted to GitHub).

  3. Every time I run your script – it returns ‘Total of 0 matching mailboxes found’ regardless of license or feature SKU selected. -> Same on my end. I’m using -> Using Azure AD cmdlets. It was working fine, 3 weeks ago.

Leave a Reply

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