Adding All Services to an Existing Office 365 User License

When working with our clients, we often find that they have enabled only some of the services within an Office 365 license.  Some companies, for example, may enable E3 licenses for a subset of users, but they don’t enable Lync Online.  While it’s very easy to add a service from within the Office 365 Admin Center, this method is not very efficient when a company has to modify several hundred or thousands of accounts and instead want to leverage Windows PowerShell.

By combining the use of the New-MsolLicenseOptions and Set-MsolUserLicense cmdlets, it’s possible to remove and add services.  In the following example, the account has been assigned all E3 services except for Office 365 ProPlus (OFFICESUBSCRIPTION) and Lync Online ‎(Plan 2) (MCOSTANDARD):


The company wants to add the Office 365 ProPlus service, but keep the Lync Online service disabled.  Running the following cmdlet will set the disabled service to only “MCOSTANDARD”:

$LicenseOptions = New-MsolLicenseOptions -AccountSkuId "company:ENTERPRISEPACK" -DisabledPlans MCOSTANDARD

Running this next cmdlet will change the license settings:

Get-MsolUser -UserPrincipalName | Set-MsolUserLicense -LicenseOptions $LicenseOptions

Since the “OFFICESUBSCRIPTION” service was not explicitly excluded in the “DisabledPlans” parameter, by default, it will now be enabled:


Note that the “ProvisioningStatus” for OFFICESUBSCRIPTION changed from “Disabled” to “PendingInput”.  When viewing the license settings in the Admin Center, the service will now be enabled under the E3 license details:


Now, again consider the scenario where a company has assigned E3 licenses, but left the Office 365 ProPlus and Lync Online (Plan 2) services disabled for all E3 licensed users.  The company now wants to enable all services, and not exclude any services.  In the past, Microsoft support has always provided that the only way to accomplish this is to remove the license, then reassign it without any “LicenseOptions”, effectively enabling all services.  While this method is perfectly safe, some companies are a bit apprehensive to make this change to a large number of accounts at once, for fear of disconnecting the users’ mailboxes and causing a service outage.

Instead of removing and re-adding the license, it’s possible to accomplish the same task by setting the “DisabledPlans” parameter to “$Null” within the “New-MsolLicenseOptions” cmdlet.  Example:

$LicenseOptions = New-MsolLicenseOptions -AccountSkuId "company:ENTERPRISEPACK" -DisabledPlans $Null
Get-MsolUser -UserPrincipalName | Set-MsolUserLicense -LicenseOptions $LicenseOptions

Note that both the OFFICESUBSCRIPTION and the MCOSTANDARD “ProvisioningStatus” have changed to “PendingInput”, and the services will show as enabled under the E3 license details in the Admin Center:



I hope you find this tip useful when managing your Office 365 licenses with Windows PowerShell.

Barry Thompson
Principal Consultant

Powershell – Get started with the low-hanging fruit

Much has been written about PowerShell (PS) cmdlets, whether they be the new ones available in v3, the Quest tools, those built into various products like SQL Server and Citrix XenDesktop, or the PSCX community extensions (to name just a few). These cmdlets are great, but don’t forget that PS is an object-oriented, interpreted scripting language, capable of taking advantage of .NET APIs and COM objects like IE and MS Word. Need to write a utility with a graphical interface so the help desk can easily provision a service for a user? Use the .NET System.Drawing and System.Windows.Forms namespaces. Want to open a web page repeatedly to ‘screen scrape’ it? Create a new object of type ‘InternetExplorer.Application’ and have at it!

Admittedly, there is a learning curve involved here, but here are some PS examples that allow you to use PowerShell quickly you may have overlooked:

1. Use the get-process cmdlet when tracking down the process that is causing performance problems. Combine that with the out-gridview and you can add additional selection criteria, and then select just the processes you want to output:

Get-process | out-gridview –passthru | fl

1a  1b 1c

2. The out-gridview is fine if you have a small amount of data, but you need more automation if you have a large base. Combining the built-in csvde.exe with import-csv lets you scale to larger sizes:

Csvde –f users.csv


$users = import-csv users.csv

$users | where {$_.sAMAccountName.StartsWith(“S”)} | select name


3. Let’s gather CPU, memory, and disk statistics. Let’s write a PS workflow (PSFW, new with v3) that will gather all of the statistics in parallel, then pass it an array of the performance counters provided by perfmon we want to examine:

Workflow gather_stats ($perfmoncounters)
    Foreach –parallel ($counter in $perfmoncounters)
      (Get-counter $counter). CounterSamples
$arr_perfmoncounters = ‘\Processor(_Total)\% Processor Time’, `
      ’\Memory\Available Bytes’, `
      ‘\PhysicalDisk(_Total)\% Disk Time’


4. MS Excel is a powerful tool. Can PS export data into a format Excel can use? Yes it can! This example uses the Quest ActiveRoles Management Shell for Active Directory (ARMS), but you could also use get-user from the Exchange PS management tools, etc., then export the results to a comma separated value (CSV) file that Excel can import:

Get-QADUser | Export-Csv -NoTypeInformation -Encoding OEM users.csv


MS Excel can open the resulting file, and you can sort, filter, etc., as you normally would inside Excel.

5. All of the examples I have given show how to read data, but what if you want to write data back into AD? No problem! Just combine the earlier examples to gather your data, then send the results into the built-in MS tool dsmod.exe:


And, since I am encouraging you to mix-and-match tools, what if you want to use the Quest ARMS commands and the Exchange cmdlets (for example) at the same time? Here’s a command that will load all of the PS modules you have installed on your system into a single PS session. Open up a PS window and use this command, courtesy of the Microsoft Scripting Guys:

Get-Module -ListAvailable | Import-Module


Just a caveat for those of you running Exchange 2007 or 2010: These products have not been updated to use v3 of PowerShell yet, so hold off installing it until MS says it is safe.

And for those of you who looked at remoting in v2: PS v2 introduced remoting, but v3 makes the whole thing more robust and reliable. If v2 remoting left you with a bad taste, give it a fresh try with v3 – I guarantee you will have a better experience!

John Scaggs, MCT, MCITP

Senior Consultant, Advanced Infrastructure Group