Granular License Assignment Office 365

In this previous article, we made basic license assignments to users in Office 365 using PowerShell.  When I say basic, the method is the simplest way to create an AD user, mailbox in Office 365, and enable all of the license options (Exchange Online, Office 365 ProPlus, Office Online, etc.) within a specific subscription license (Office 365 Enterprise E3, Enterprise Mobility Suite, etc.).


The following instructions will provide the ability to granularly enable license options by disabling the products within a specific subscription we do not want to use. What is odd to me is that to enable a license option in Office 365 we must disable the options we do not want enabled. It seems backwards, but it is what it is.

NOTE: This article makes an assumption that user accounts are present in Office 365 through manual addition or syncing from on premises.



First, Connect to Office 365 with PowerShell.



Before a subscription license and license options can be applied, a usage location is required to be assigned for each user that will be using Office 365 resources. This next command will assign the usage location of “US” (United States of America) for every unlicensed user in an Office 365 tenant.

NOTE: Other two letter country codes used by Microsoft can be found here.

Get-MsolUser -UnlicensedUsersOnly -All | Set-MsolUser -UsageLocation “US”

…or we can assign a usage location for an individual user using this command.

Set-MsolUser -UserPrincipalName -UsageLocation "US"

…or we can assign a usage location for list of O365 users using a CSV file and subsequent command.

This is an example of the CSV file used…

Import-Csv "C:\Scripts\MyO365Users.csv" | ForEach-Object { Set-MsolUser -UserPrincipalName $_.MyUPN -UsageLocation $_.MyUsageLocation }



From the PowerShell console, run the following command to get the subscription license SKU ID(s), license options and number of remaining licenses for each subscription in the Office 365 tenant.

Get-MsolAccountSku | %{$_.accountskuID;Write "Remaining Licenses:";($x =$_.ActiveUnits - $_.ConsumedUnits);$_.ServiceStatus | ft -hide}

The following are some subscriptions that may exist for an Office 365 tenant.

NOTE: Document the “tenantname” after running this command as it will be used in later.

tenantname:AAD_BASIC  (Azure Active Directory Basic)

tenantname:ENTERPRISEPACK  (Office 365 Enterprise E3)

tenantname:INTUNE_A  (Intune A Direct)

tenantname:EMS  (Enterprise Mobility Suite)


These are some of the license options within the Office 365 Enterprise E3 subscription. Take note of the license options available  in the tenant (after running the prior command) as they may and will vary for each O365 customer and as new features are added.


SWAY  (Sway)

INTUNE_O365  (Mobile Device Management for Office 365)

YAMMER_ENTERPRISE  (Yammer Enterprise)

RMS_S_ENTERPRISE  (Azure Rights Management)


MCOSTANDARD  (Skype for Business Online)

SHAREPOINTWAC  (Office Online)




These are some of the license options within the Enterprise Mobility Suite subscription…

RMS_S_PREMIUM  (Azure Rights Management Premium)
INTUNE_A  (Intune A Direct)
RMS_S_ENTERPRISE  (Azure Rights Management)
AAD_PREMIUM  (Azure Active Directory Premium)
MFA_PREMIUM  (Azure Multi-Factor Authentication)




Now that we’ve assigned a usage location for users and know what license subscriptions and options we have in the tenant, this next set of commands will assign a subscription license and license options for an individual user.  In this case, only Exchange Online will be enabled for the user—all other options are disabled.

NOTE: “Exchange Online” is not listed in the parameter for DisabledPlans because we are enabling the option for use.

$MyLicenseOptions = New-MsolLicenseOptions -AccountSkuId "tenantname:ENTERPRISEPACK" -DisabledPlans PROJECTWORKMANAGEMENT,SWAY,INTUNE_O365,YAMMER_ENTERPRISE,RMS_S_ENTERPRISE,OFFICESUBSCRIPTION,MCOSTANDARD,SHAREPOINTWAC,SHAREPOINTENTERPRISE Set-MsolUserLicense -UserPrincipalName "" -AddLicenses "tenantname:ENTERPRISEPACK" -LicenseOptions $MyLicenseOptions



If we want to assign subscription licenses and options in bulk (the same CSV file used to assign usage location can be utilized) we will use these set of commands.

$MyLicenseOptions = New-MsolLicenseOptions -AccountSkuId "tenantname:ENTERPRISEPACK" -DisabledPlans PROJECTWORKMANAGEMENT,SWAY,INTUNE_O365,YAMMER_ENTERPRISE,RMS_S_ENTERPRISE,OFFICESUBSCRIPTION,MCOSTANDARD,SHAREPOINTWAC,SHAREPOINTENTERPRISE Import-Csv "C:\Scripts\MyO365Users.csv" | ForEach-Object { Set-MsolUserLicense -UserPrincipalName $_.MyUPN -AddLicenses "tenantname:ENTERPRISEPACK" -LicenseOptions $MyLicenseOptions }

REMEMBER: If we use the same variable name (such as $MyLicenseOptions) in subsequent commands without either closing PowerShell or clearing the value of the variable (i.e. $MyLicenseOptions = $null), there is a high probability we will receive errors when making our additional license assignments.



If we wish to modify the existing assigned license options on a user that has already been assigned a license we use these two commands. Remember, we already have Exchange Online assigned to my user. If we want to enable Office 365 ProPlus (OFFICESUBSCRIPTION) and Skype for Business Online (MCOSTANDARD) for that user we need to remove the license options from the “DisabledPlans” parameter to enable them.  In this example, accessibility to use Skype for Business Online and download Office 365 ProPlus is made available.

NOTE: The Set-MsolUserLicense in this set of commands is slightly different from the previous set of commands in that we are not using the AddLicenses parameter.

$MyLicenseOptions = New-MsolLicenseOptions -AccountSkuId "tenantname:ENTERPRISEPACK" -DisabledPlans PROJECTWORKMANAGEMENT,SWAY,INTUNE_O365,YAMMER_ENTERPRISE,RMS_S_ENTERPRISE,SHAREPOINTWAC,SHAREPOINTENTERPRISE Set-MsolUserLicense -UserPrincipalName "" -LicenseOptions $MyLicenseOptions



IMPORTANT: If we want to assign Office Online as a license option for any user, SharePoint Online (Plan 2)must be enabled either before or in tandem. If we attempt to assign Office Online without assigning SharePoint Online (Plan 2), we will receive one of the following error depending on where we attempt to make the product assignment. As of today, there aren’t any other product dependencies that I have come across.



And, if we want to modify license options in bulk (the same CSV file used to assign usage location can be utilized) we will use these set of commands.

$MyLicenseOptions = New-MsolLicenseOptions -AccountSkuId "tenantname:ENTERPRISEPACK" -DisabledPlans PROJECTWORKMANAGEMENT,SWAY,INTUNE_O365,YAMMER_ENTERPRISE,RMS_S_ENTERPRISE,SHAREPOINTWAC,SHAREPOINTENTERPRISE Import-Csv "C:\Scripts\MyO365Users.csv" | ForEach-Object { Set-MsolUserLicense -UserPrincipalName $_.MyUPN -LicenseOptions $MyLicenseOptions }


Finally, if we choose to enable all of the products available in out Office 365 Enterprise E3 subscription, we will set the value for the DisabledPlans parameter to $null and the run the command to make the assignments for individual users or in bulk.



In this article, we connect to our Office 365 tenant through PowerShell, set usage locations for users, set a subscription license, and assign granular license options for users to access resources in O365.


Good luck and have fun!


My Related Articles:




Like this:


28 June 2016 in Office 365, PowerShell. Tags: AAD_BASIC, AAD_PREMIUM, accountskuid, add licenses, addlicenses, Azure Active Directory Basic, Azure Active Directory Premium, Azure Multi-Factor Authentication, azure rights management, Azure Rights Management Premium, disabledplans, ems, Enterprise Mobility Suite, ENTERPRISEPACK, exchange online, EXCHANGE_S_ENTERPRISE, Intune A Direct, INTUNE_A, INTUNE_O365, license options, licenseoptions, MCOSTANDARD, MFA_PREMIUM, Microsoft Planner, Mobile Device Management for Office 365, new-msollicenseoptions, o365, office 365, Office 365 Enterprise E3, office 365 proplus, Office Online, OFFICESUBSCRIPTION, powershell, PROJECTWORKMANAGEMENT, RMS_S_ENTERPRISE, RMS_S_PREMIUM, set-msoluser, set-msoluserlicense, sharepoint online, SHAREPOINTENTERPRISE, SHAREPOINTWAC, skype for business online, SWAY, usage location, usagelocation, Yammer Enterprise, YAMMER_ENTERPRISE

Important note: The end of an era with licensing scripts is near… and the beginning of a new one with Azure AD Group Based Licensing is here. Group Based Licensing is now in preview and currently requires a paid Azure AD Subscription. Try it out and give Microsoft your feedback on how they can make it even better! 

The never ending story about Office 365 licensing continues… This time it’s an extension of my script to assign licenses based on groups, with additional functionality to remove and change licenses for users.
I’ve come across scenarios where this have been a requirement a couple of times, and wanted to see how much work that was required to get the job done. 🙂

If you just want to assign licenses for users based on groups, plain and simple, this is not the script for you…

Running the script
The script is tested in a tenant with two different license types (E1 and E3). Therefore, the functionality has been verified against that, so if you have three or four different licenses to assign in your tenant, you have to do your own testing! 🙂

The following functions are included in the script:

  • Assignment of licenses for new users based on groups/licenseSKU’s in the $licenses hashtable
  • Switch of licensetype if a user is moved from one group to another
  • Removal of license if the user no longer is a member in any of the license assignment groups

IMPORTANT:Since the script actually will remove licenses for users that are not in any of the groups, you have to make sure that you populate the license assignment groups prior to first time running the script.

Apart from the above, the script requirements and setup details are the same as in this post.


<# .SYNOPSIS Script that assigns Office 365 licenses based on Group membership in WAAD. .DESCRIPTION The script assigns of licenses for new users based on groups/licenseSKUs in the $licenses hashtable. It switch licensetype if a user is moved from one group to Another. It removes the license if the user no longer is a member in any of the license assignment Groups. Updated 2015-03-25 to support multiple skus for each user. The script REQUIRES PowerShell 3.0 or later! .NOTES Author: Johan Dahlbom Blog: Email: johan[at] The script are provided “AS IS” with no guarantees, no warranties, and they confer no rights. #> #Import Required PowerShell Modules Import-Module MSOnline #Office 365 Admin Credentials $CloudUsername = '' $CloudPassword = ConvertTo-SecureString 'Password' -AsPlainText -Force $CloudCred = New-Object System.Management.Automation.PSCredential $CloudUsername, $CloudPassword #Connect to Office 365 Connect-MsolService -Credential $CloudCred $Licenses = @{ 'E1' = @{ LicenseSKU = 'mstlabs:STANDARDPACK' Group = 'E1_Users' } 'E3' = @{ LicenseSKU = 'mstlabs:ENTERPRISEPACK' Group = 'E3_Users' } } $UsageLocation = 'SE' #Get all currently licensed users and put them in a custom object $LicensedUserDetails = Get-MsolUser -All | Where-Object {$_.IsLicensed -eq 'True'} | ForEach-Object { [pscustomobject]@{ UserPrincipalName = $_.UserPrincipalName License = $_.Licenses.AccountSkuId } } #Create array for users to change or delete $UsersToChangeOrDelete = @() foreach ($license in $Licenses.Keys) { #Get current group name and ObjectID from Hashtable $GroupName = $Licenses[$license].Group $GroupID = (Get-MsolGroup -All | Where-Object {$_.DisplayName -eq $GroupName}).ObjectId $AccountSKU = Get-MsolAccountSku | Where-Object {$_.AccountSKUID -eq $Licenses[$license].LicenseSKU} Write-Output "Checking for unlicensed $license users in group $GroupName with ObjectGuid $GroupID..." #Get all members of the group in current scope $GroupMembers = (Get-MsolGroupMember -GroupObjectId $GroupID -All).EmailAddress #Get all already licensed users in current scope $ActiveUsers = ($LicensedUserDetails | Where-Object {$_.License -eq $licenses[$license].LicenseSKU}).UserPrincipalName $UsersToHandle = '' if ($GroupMembers) { if ($ActiveUsers) { #Compare $Groupmembers and $Activeusers #Users which are in the group but not licensed, will be added #Users licensed, but not, will be evaluated for deletion or change of license $UsersToHandle = Compare-Object -ReferenceObject $GroupMembers -DifferenceObject $ActiveUsers -ErrorAction SilentlyContinue -WarningAction SilentlyContinue $UsersToAdd = ($UsersToHandle | Where-Object {$_.SideIndicator -eq '<='}).InputObject $UsersToChangeOrDelete += ($UsersToHandle | Where-Object {$_.SideIndicator -eq '=>'}).InputObject } else { #No licenses currently assigned for the license in scope, assign licenses to all group members. $UsersToAdd = $GroupMembers } } else { Write-Warning "Group $GroupName is empty - will process removal or move of all users with license $($AccountSKU.AccountSkuId)" #If no users are a member in the group, add them for deletion or change of license. $UsersToChangeOrDelete += $ActiveUsers } #Check the amount of licenses left... if ($AccountSKU.ActiveUnits - $AccountSKU.consumedunits -lt $UsersToAdd.Count) { Write-Warning 'Not enough licenses for all users, please remove user licenses or buy more licenses' } foreach ($User in $UsersToAdd){ #Process all users for license assignment, if not already licensed with the SKU in order. if ((Get-MsolUser -UserPrincipalName $User).Licenses.AccountSkuId -notcontains $AccountSku.AccountSkuId) { try { #Assign UsageLocation and License. Set-MsolUser -UserPrincipalName $User -UsageLocation $UsageLocation -ErrorAction Stop -WarningAction Stop Set-MsolUserLicense -UserPrincipalName $User -AddLicenses $AccountSKU.AccountSkuId -ErrorAction Stop -WarningAction Stop Write-Output "SUCCESS: Licensed $User with $license" } catch { Write-Warning "Error when licensing $User" } } } } #Process users for change or deletion if ($UsersToChangeOrDelete -ne $null) { foreach ($User in $UsersToChangeOrDelete) { if ($user -ne $null) { #Fetch users old license for later usage $OldLicense = ($LicensedUserDetails | Where-Object {$_.UserPrincipalName -eq $User}).License #Loop through to check if the user group assignment has been changed, and put the old and the new license in a custom object. #Only one license group per user is currently supported. $ChangeLicense = $Licenses.Keys | ForEach-Object { $GroupName = $Licenses[$_].Group if (Get-MsolGroupMember -All -GroupObjectId (Get-MsolGroup -All | Where-Object {$_.DisplayName -eq $GroupName}).ObjectId | Where-Object {$_.EmailAddress -eq $User}) { [pscustomobject]@{ OldLicense = $OldLicense NewLicense = $Licenses[$_].LicenseSKU } } } if ($ChangeLicense) { #The user were assigned to another group, switch license to the new one. try { Set-MsolUserLicense -UserPrincipalName $User -RemoveLicenses $ChangeLicense.OldLicense -AddLicenses $ChangeLicense.NewLicense -ErrorAction Stop -WarningAction Stop Write-Output "SUCCESS: Changed license for user $User from $($ChangeLicense.OldLicense) to $($ChangeLicense.NewLicense)" } catch { Write-Warning "Error when changing license on $User`r`n$_" } } else { #The user is no longer a member of any license group, remove license Write-Warning "$User is not a member of any group, license will be removed... " try { Set-MsolUserLicense -UserPrincipalName $User -RemoveLicenses $OldLicense -ErrorAction Stop -WarningAction Stop Write-Output "SUCCESS: Removed $OldLicense for $User" } catch { Write-Warning "Error when removing license on user`r`n$_" } } } } }

Hope this helps you if having this scenario, please let me know if you have features requests or other things that can improve the script!


Like this:



This entry was posted in Office 365, PowerShell and tagged license script switch license, office 365 remove license, office 365 switch license, Office365 license assignment; set-msoluserlicense; office 365 license switch;office 365 license removal group, Set-MsolUserLicense on by Johan Dahlbom.

One thought on “Granular License Assignment Office 365

Leave a Reply

Your email address will not be published. Required fields are marked *