Enabling or Disabling Specific Services Within Your Office365 License using Powershell

As I’ve discussed in previous posts, an Office365 “License”, which Microsoft refers to as an AccountSkuID, can be conceptualized as a bundle of services which make up that license offering.  For example, in the educational tenant that I am working with at the moment, the license “STANDARDWOFFPACK_STUDENT” can grant a person access to a number of services, such as Exchange Online, Sharepoint Online, OneDrive, the Office web apps, Skype for Business, and a few other things.

A frequent request I’ve had is for a way to easily turn on or off specific services for a user or a set of users.  This is easy enough to do via the Office365 admin portal by flipping the toggles on the screen, but that obviously won’t scale.  Also, the trick is to make sure that you toggle the setting for the one service plan you are looking for while leaving all of the other service plans in their current states.

The approach that I’ve settled on to manipulate a single service plan’s status within an Office365 license is as follows:

  • Read the target user’s object from AAD using get-msoluser.
    $userObject = get-msoluser -UserPrincipalName $userPrincipalName
  • Create a hashtable of ServicePlan:ProvisioningStatus values for all of the service plans in the user’s current license.
    $plans = @{}
    $userObject.licenses.servicestatus | % { $plans.add($_.serviceplan.servicename, $_.provisioningstatus) }
  • Look for a key in the hashtable you just created which matches the name of the service plan that we are looking for and set it to the desired value.  In this example, we are disabling the service plan by changing it from “Success” to “Disabled” in the hashtable.
    if ($plans.get_item($targetServicePlan) -eq "Success") {
  • Use the values in the updated hashtable to build a new licenseOptions object with the updated set of disabled service plans.
    The New-msolLicense opject seems to be very picky about the value passed to the disabledPlans parameter.  The only way that I have found which works consistently is to create a list (array) with each item in the list being a service plan name.  Some sources seem to suggest that a comma-separated string will work but I haven’t had much luck with that.

    $disabledPlans = @()
    $plans.Keys | % { if ($plans.get_item($_) -eq "Disabled") { $disabledPlans += $_ } }
    if ($disabledPlans) {
        $licenseOptions = new-msolLicenseOptions -AccountSkuId $baseLicense -DisabledPlans $disabledPlans -verbose
    } else { # If there is nothing on the list of disabled services
        $licenseOptions = new-msolLicenseOptions -AccountSkuId $baseLicense
  • Use Set-msoluserlicense to apply the updated license information to the target user.
    get-msoluser -UserPrincipalName $userObject.userprincipalname | Set-MsolUserLicense -LicenseOptions $licenseOptions

You can find a pair of Powershell scripts named enable-O365ServicePlan.ps1 and disable-O365ServcicePlan.ps1, which demonstrate this approach, at my GitHub repo.  The scripts perform a series of checks to make sure that the target user is in the correct state before any changes are made.

A limitation of these scripts is that they only handle cases where the target user has a single license assigned to them.  While a single license is the most common configuration, users may also have more than one license assigned and the scripts do not handle that use case.


Using Powershell custom tables to get more useful license usage information from O365

When you want to check the number of licenses in your O365 environment, you use the command get-msolaccountsku, which returns a set of information on the licenses that are part of your environment.  This shows the total number of licenses, the number that have been assigned to users (“consumed”) and the number of licenses that are in a warning state.

While working with a customer that has a number of active SKU ID’s, I needed to improve on this to add a column which has a count of unassigned licenses for easy reference, so here’s a Powershell script which is also a simple example of how you can use custom table formats to generate custom output on the fly.

Most of the format entries are a straight replica of what comes back from the get-msolaccountsku command but the line highlighted in red does a calculation to show the number of unassigned licenses for that SkuID.  The expression element of a table format is in the form of a script block so you can do some really interesting stuff by inserting whatever code you want.  Inside the block, the $_ variable refers to the object that the table is processing at that particular moment

# get-o365licensecounts.ps1
# Outputs license information for O365 including a column showing # of unassigned licenses by SKU
# Format string to define the table
$f = @{expr={$_.AccountSkuID};label="AccountSkuId"},

# output the info using the format we just defined.
# sorted by active units -descending.
Get-MsolAccountSku | sort activeunits -desc | ft $f -auto

Default output from get-msolaccountsku:..

… and with the script using the custom format…:

Much better.

For more information on how custom tables work, see this TechNet article.