Modify-Sublicense PowerShell function for modifying Office 365 Sublicenses


An example call would be:

Modify-Sublicense -upn "" -PrimaryLicense "TENANT:ENTERPRISEPACK" -SublicensesToRemove @("SWAY","YAMMER_ENTERPRISE") -SublicensesToAdd @("SHAREPOINTENTERPRISE", "SHAREPOINTWAC")

If you’re new to powershell, scroll down past the code below for some additional tips.

Naturally, sublicenses you had before will REMAIN unless you’ve removed them.
Sublicenses you DID NOT HAVE before will NOT BE ADDED unless you specifically add them.

This is important because of how the licensing works, which has been covered in other blog posts my myself and others.

I’ve used the function below as part of a larger script with good results.


## this function Adds and or removes sublicenses 
## Pass in the -SublicensesToAdd and -SublicensesToRemove as an array ( use $var = @("value", "Value")  )
##  to a user's Pre-Existing License (for example TENANT:ENTERPRISEPACK)
function Modify-SubLicense($upn, $PrimaryLicense, $SublicensesToAdd, $SublicensesToRemove)
	$spouser = get-msoluser -userprincipalname $upn
	#assemble a list of sub-licenses types the user has that are currently disabled, minus the one we're trying to add 
	$disabledServices = $($spouser.Licenses | where {$_.AccountSkuID -eq $PrimaryLicense}).servicestatus | where {$_.ProvisioningStatus -eq "Disabled"}  | select -expand serviceplan | Select ServiceName 
	#disabled items need to be in an array form, next 2 lines build that...
	$disabled = @()
	foreach  ($item in $disabledServices.servicename) {$disabled += $item}
	write-host "   DisabledList before changes: $disabled" -foregroundcolor yellow
	#if there are other sublicenses to be removed (Passed in via -SublicensesToRemove) then lets add those to the disabled list.
	foreach  ($license in $SublicensesToRemove)
		$disabled += $license 
	#cleanup duplicates in case the license to remove was already missing
	$disabled = $disabled | select -unique
	#If there are licenses to ADD, we need to REMOVE them from the list of disabled licenses
	$disabled = $disabled | ?{$SublicensesToAdd -notContains $_}
	write-host "    DisabledList after changes: $Disabled" -foregroundColor green
    $LicenseOptions = New-MsolLicenseOptions -AccountSkuId $PrimaryLicense -DisabledPlans $disabled
	set-msoluserlicense  -userprincipalname $upn -licenseoptions  $LicenseOptions

New to powershell?

Here are a few tips:

  • Since the code is a function, you’ll need to copy-paste it to a script of your own before you can use it
  • In powershell, functions need to appear in your script above/before you use them.
  • There are ways to load the function in memory, so you can call it as if it was a native command. See How to add functions to your powershell session
  • An array in powershell can have zero or 1 or many items, if you need to pass a single value, just pass it as an array with one value. That would look like this: @("Value1", "Value2")

– Jack

9 thoughts on “Modify-Sublicense PowerShell function for modifying Office 365 Sublicenses

  1. Excuse my ignorance, but when I try to run the call you have at the start of this page (Modify-Sublicense….) powershell goes to a double arrow prompt

    For example…

    PS C:\windows\system32> Modify-Sublicense -upn “” -PrimaryLi
    cense “xxxxx:STANDARDPACK -SublicensesToAdd @(“TEAMS1”, “PROJECTWORKMANAGEMENT”)
    >> (cursor flashes here)

    I tried removing the quote from the beginning of the tenant name:skuid but when I did that it returned an error stating:

    Modify-Sublicense : The term ‘Modify-Sublicense’ is not recognized as the name
    of a cmdlet, function, script file, or operable program. Check the spelling of
    the name, or if a path was included, verify that the path is correct and try

    Is “modify-sublicense” a legitimate powershell command?

    1. Hi, great question – this is the name of a function, and the code for the function is in the article.

      It’s not meant to work one off – it’s meant to be included in a script.

      If you create a ps1 file – call it jason.ps1, and copy and paste the function from the article in, and then at the end, you can call the function, using the sample as a guide, that should work for you.

  2. This was a bit of a lifesaver for me when we had to license users who had both E3 and E5 at the same time.. I have always been under the impression that i first need to remove the license and re-add with the new sublicenses.

    Going from your script, i found that it is not the case and it can be simply added by re-applying the license, not sure if that was the case earlier or if it changed in between.

    but saved my work today..!

  3. Thank you. I’ve been running a script that sort of does this (yours is much cleaner) but I have a need to first query what services are active, modify (usually disable new service that MS has released), then i need to ensure that the previously queried services are replaced without overriding the modification i just made.

    Case in point, I have ~25 users with Teams enabled; I have ~25 users with Planner enabled; I have ~25 users with Stream enabled; there is some overlap but they are not all the same users. Now I need to go through and disable ToDo on all users. But if I follow mine, yours, anybody elses’ script, I override those individual services. Right now, I’m keeping track of those individual exceptions using Excel… NOT efficient and not scalable for future rollouts of services. And I do NOT have Azure Premium (to be able to add to different licensing groups).

    Any suggestions? 🙂

    1. Hi julie, sorry for the late reply, hopefully you’ve solved this, but I’ll comment here for others.

      If you just need to ‘inject’ a sublicense, that’s easy to do without adding other license types and the script on this post should be able to help with that.
      On the other hand, if you’re trying to ‘enforce’ a set of sublicense rules, and those rules are different for different groups of users, then you’ll have to build in some logic, and it will be a bit messy.

      Instead of using Excel, I would use a csv file for each list of users



      each CSV should have one email address per line.

      you can load these into your powershell code via something like $teamsusers = import-csv teams.csv

      now you’ll have all the people that need teams in that $teamsusers variable

      Then when you enumerate through your users assigning licenses, you can check each user to see if they are present in the $teamsusers variable, and if so act on them accordingly.

      Doing the same for each of your special exceptions, should let you build a set of sublicenses that specific user requires, and then you can apply that.

    1. Thanks Johan for pointing this out! A mistake on my part not proofing it and I’m sure it threw off at least one person, so I appreciate you bringing it up, I’ve updated the post.
      – Jack

Leave a Reply