Assign Specific Licences in Office 365 Via PowerShell


 

To add specific licences to users in Office 365 without using the portal, and to assign subsets of the licences available requires two things. First you need to enumerate the licences and licence service plans, then you need to assign the new plan you have created to your users. This can be performed in bulk and is repeatable unlike when using the portal.
First, enumerate the licence plans and create your own licence:

  1. Open Microsoft Online Services Module for Windows PowerShell and connect to the service
    • $cred = Get-Credential
    • Connect-MsolService -Credential $cred
  2. Get-MsolAccountSku | Format-Table AccountSkuId, SkuPartNumber
    • The second column in this list is referenced in the next command as [SkuPartNumber]
  3. $ServicePlans = Get-MsolAccountSku | Where {$_.SkuPartNumber -eq “[SkuPartNumber]”}
  4. $ServicePlans.ServiceStatus
    • This returns all the service plans
  5. $MyO365Sku = New-MsolLicenseOptions -AccountSkuId [tenantname:AccountSkuId] -DisabledPlans Comma_Seperated_List_From_ServicePlans_Output

Secondly you need to assign the licence to the user(s):

  1. Set-MsolUser -UserPrincipalName user@domain.com -UsageLocation GB
  2. Set-MsolUserLicense -UserPrincipalName user@domain.com -AddLicenses [tenantname:AccountSkuId] -LicenseOptions $MyO365Sku
  3. Repeat for any other licences you want to apply for other users or other licence options you want to apply to this user.

For reference, the SkuPartNumber’s that we discovered are:

Inside ENTERPRISEPREMIUM_NOPSTNCONF (E5 without PSTN Conferencing) Sku:

  • EQUIVIO_ANALYTICS
  • LOCKBOX_ENTERPRISE
  • EXCHANGE_ANALYTICS
  • SWAY
  • ATP_ENTERPRISE
  • MCOEV
  • BI_AZURE_P2
  • INTUNE_O365
  • PROJECTWORKMANAGEMENT
  • RMS_S_ENTERPRISE
  • YAMMER_ENTERPRISE
  • OFFICESUBSCRIPTION
  • MCOSTANDARD
  • EXCHANGE_S_ENTERPRISE
  • SHAREPOINTENTERPRISE
  • SHAREPOINTWAC

Inside ENTERPRISEPREMIUM (E5) Sku:

  • EQUIVIO_ANALYTICS
  • LOCKBOX_ENTERPRISE
  • EXCHANGE_ANALYTICS
  • SWAY
  • ATP_ENTERPRISE
  • MCOEV
  • BI_AZURE_P2
  • INTUNE_O365
  • PROJECTWORKMANAGEMENT
  • RMS_S_ENTERPRISE
  • YAMMER_ENTERPRISE
  • OFFICESUBSCRIPTION
  • MCOSTANDARD
  • EXCHANGE_S_ENTERPRISE
  • SHAREPOINTENTERPRISE
  • SHAREPOINTWAC
  • MCOMEETADV (PSTN Conferencing)
  • BPOS_S_TODO_2 (To Do)
  • FLOW_O365_P2 (Flow)
  • FORMS_PLAN_E3
  • POWERAPPS_O365_P3
  • STREAM_O365_E3
  • TEAMS1

Inside ENTERPRISEPACK (E3) Sku:

  • YAMMER_ENTERPRISE (Yammer – though you cannot apply this individually or disable it individually, so ignore it for the purposes of this script)
  • OFFICESUBSCRIPTION (this is Office Professional Plus)
  • MCOSTANDARD (this is Skype for Business Online)
  • SHAREPOINTWAC (this is Office Web Apps)
  • SHAREPOINTENTERPRISE
  • EXCHANGE_S_ENTERPRISE (Exchange Plan 2)
  • RMS_S_ENTERPRISE (Azure Rights Management)
  • INTUNE_O365 (Mobile Device Management for Office 365)
  • SWAY
  • BPOS_S_TODO_2 (To Do)
  • FLOW_O365_P3 (Flow)
  • FORMS_PLAN_E5
  • POWERAPPS_O365_P3
  • STREAM_O365_E5
  • TEAMS1
  • MCOEV
  • LOCKBOX_ENTERPRISE
  • BI_AZURE_P2
  • THREAT_INTELLIGENCE
  • EQUIVIO_ANALYTICS

Inside Enterprise Mobility Pack (EMS)

  • RMS_S_PREMIUM
  • INTUNE_A
  • RMS_S_ENTERPRISE
  • AAD_PREMIUM
  • MFA_PREMIUM

Inside ENTERPRISEPACKWITHOUTPROPLUS sku

  • YAMMER_ENTERPRISE
  • SHAREPOINTWAC
  • SHAREPOINTENTERPRISE
  • RMS_S_ENTERPRISE
  • MCOSTANDARD
  • EXCHANGE_S_ENTERPRISE
  • INTUNE_O365

Inside DESKLESSWOFFPACK Sku:

  • SHAREPOINTWAC
  • SHAREPOINTDESKLESS
  • EXCHANGE_S_DESKLESS

Inside EXCHANGESTANDARD sku

  • INTUNE_O365
  • EXCHANGE_S_STANDARD

Inside EXCHANGEENTERPRISE sku

  • INTUNE_O365
  • EXCHANGE_S_ENTERPRISE

Inside EXCHANGEARCHIVE Sku

  • EXCHANGE_S_ARCHIVE

Inside P1 (Small Business) Tenants

  • MCOLITE
  • SHAREPOINTLITE
  • EXCHANGE_L_STANDARD

Inside K1 – DESKLESSPACK

  • SHAREPOINTDESKLESS
  • EXCHANGE_S_DESKLESS

Inside K2 – DESKLESSWOFFPACK

  • SHAREPOINTWAC
  • SHAREPOINTDESKLESS
  • EXCHANGE_S_DESKLESS

Inside P1 – LITEPACK

  • MCOLITE
  • SHAREPOINTLITE
  • EXCHANGE_L_STANDARD

Inside E1 – STANDARDPACK

  • MCOSTANDARD
  • SHAREPOINTSTANDARD
  • EXCHANGE_S_STANDARD

Inside E4 – ENTERPRISEWITHSCAL

  • YAMMER_ENTERPRISE
  • OFFICESUBSCRIPTION
  • MCOSTANDARD
  • SHAREPOINTWAC
  • SHAREPOINTENTERPRISE
  • EXCHANGE_S_ENTERPRISE
  • RMS_S_ENTERPRISE

Inside PowerBI Standalone (POWER_BI_STANDALONE)

  • YAMMER_ENTERPRISE
  • SQL_IS_SSIM
  • BI_AZURE_P1
  • SHAREPOINTENTERPRISE

Inside Project Online (PROJECTONLINE_PLAN_1)

  • SWAY
  • SHAREPOINT_PROJECT
  • SHAREPOINTWAC
  • SHAREPOINTENTERPRISE

Inside Project Lite (PROJECTESSENTIALS)

  • SWAY
  • SHAREPOINTWAC
  • SHAREPOINTENTERPRISE
  • PROJECT_ESSENTIALS

Inside Academic A2 Plans

  • SHAREPOINTWAC_EDU
  • MCOSTANDARD
  • SHAREPOINTSTANDARD_EDU
  • EXCHANGE_S_STANDARD

Inside Medium Business Sku (contoso:MIDSIZEPACK)

  • SHAREPOINTWAC
  • OFFICESUBSCRIPTION
  • EXCHANGE_S_STANDARD_MIDMARKET
  • SHAREPOINTENTERPRISE_MIDMARKET
  • MCOSTANDARD_MIDMARKET

PowerBI Standard (POWER_BI_STANDARD)

  • BI_AZURE_P0

Visio Pro for Office 365

  • VISIOCLIENT

Project Pro for Office 365

  • PROJECTCLIENT

Skype for Business PSTN Conferencing

  • MCOMEETADV

Skype for Business PSTN Domestic and International Calling

  • MCOPSTN2

Skype for Business Cloud PBX

  • MCOEV

Microsoft Dynamics CRM Online internal use rights (IUR) benefit for MPN members

  • CRMIUR

Windows 10 Enterprise E5

  • WIN10_PRO_ENT_SUB
  • WINDEFATP

 

With thanks to Donte Henry (Avanade) and Tim Heeney (Microsoft). Discovered during the Office 365 MCM Class for Exchange 2010 MCM’s.

Updated June 2014 with the findings of some of those who added comments below. Note that some comments say you need to have an array for disabled plans – this is not what I find when I run the above.

Updated Feb 2015 with more licence pack data.

Updated June 2015 with more licence pack data (INTUNE_O365)

Updated Dec 2015 with E5/NOPSTN and new standalone licence skus

Updated Feb 2016 with E5 and PSTN Conferencing

Updated May 2016 with Skype for Business Cloud PBX and some Dynamics CRM


by

Tags:

Comments

18 responses to “Assign Specific Licences in Office 365 Via PowerShell”

  1. Brian Reid avatar

    Powershell commands corrected for US English – the cmdlets spell licence with an s near the end!

  2. Justin Barker avatar

    For those using P1 (Small Business) tenancies, the SKU components are:

    MCOLITE
    SHAREPOINTLITE
    EXCHANGE_L_STANDARD

    Hope this helps

  3. Roman avatar

    I’ve gotten this to work only a few times, only one time with multiple disabled license options.

    Here is the script I’m running:

    Get-MsolAccountSku | Format-Table AccountSkuId, SkuPartNumber

    $SKN = Read-Host “Please enter the SKU Part Number”

    $ServicePlans = Get-MsolAccountSku | Where {$_.SkuPartNumber -eq “$SKN”}

    $ServicePlans.ServiceStatus

    $SKID = Read-Host “Please enter the SKU ID”

    $DLO = Read-Host “Please enter the license options you would like to disable, separated by commasset”

    $MyO365Sku = New-MsolLicenseOptions -AccountSkuId $SKID -DisabledPlans $DLO

    $UPN = Read-Host “Please enter the User Principal Name”

    Set-MsolUserLicense -UserPrincipalName $UPN -AddLicenses $SKID -LicenseOptions $MyO365Sku

    ———————————-

    The majority of the time I get the following error, any insight?

    Set-MsolUserLicense : Unable to assign this license because it is invalid. Use the Get-MsolAccountSku cmdlet to retrieve a list of valid licenses.
    At line:1 char:20
    + Set-MsolUserLicense <<<< -UserPrincipalName $UPN -AddLicenses $SKID -LicenseOptions $MyO365Sku
    + CategoryInfo : OperationStopped: (:) [Set-MsolUserLicense], MicrosoftOnlineException
    + FullyQualifiedErrorId : Microsoft.Online.Administration.Automation.
    InvalidUserLicenseException,Microsoft.Online.
    Administration.Automation.SetUserLicense

  4. Roman avatar

    By the way, here are the components for most plans.

    K1 – DESKLESSPACK

    SHAREPOINTDESKLESS
    EXCHANGE_S_DESKLESS

    K2 – DESKLESSWOFFPACK

    SHAREPOINTWAC
    SHAREPOINTDESKLESS
    EXCHANGE_S_DESKLESS

    P1 – LITEPACK

    MCOLITE
    SHAREPOINTLITE
    EXCHANGE_L_STANDARD

    E1 – STANDARDPACK

    MCOSTANDARD
    SHAREPOINTSTANDARD
    EXCHANGE_S_STANDARD

    E2 – STANDARDWOFFPACK (?)

    E3 – ENTERPRISEPACK

    OFFICESUBSCRIPTION
    MCOSTANDARD
    SHAREPOINTWAC
    SHAREPOINTENTERPRISE
    EXCHANGE_S_ENTERPRISE

    E4 – ENTERPRISEWITHSCAL

    OFFICESUBSCRIPTION
    MCOSTANDARD
    SHAREPOINTWAC
    SHAREPOINTENTERPRISE
    EXCHANGE_S_ENTERPRISE

  5. Brian Reid avatar

    @Roman, what are you entering for $SKID? It needs to be your TennantID:SKU

  6. Roman avatar

    Brian,

    I am using, for example, contoso:enterprisepack

    Like I said, when I first wrote the script, it worked fine, and now it doesn’t.

    So I’m not sure what is going on. At times I can get it to work with just one disabled license option, but not multiple anymore.

    Even a single license option is only about 5% of the time.

    Roman

  7. Roman avatar

    After playing around with this a bit more using PowerGui I noticed that when you create the $MyO365Sku variable, it does not read $DLO properly.

    If I manually do this step, everything works properly.

  8. Roman avatar

    Just a final followup to my issue.

    The variable $DLO was not being read as an array which was causing the -DisabledPlans parameter to not read the input as a comma separated value.

    To make the script work the variable needs to be:

    $arrayDLO = (Read-Host “Please enter the license options, separated by commas with no space”).Split(“,”)

  9. Brian Reid avatar

    Thanks @Roman. If you post the entire script to your own blog then I will paste a link here, or you are welcome to add the working script to the bottom.

  10. Roman avatar

    Get-MsolAccountSku | Format-Table AccountSkuId, SkuPartNumber

    $SKN = Read-Host “Please enter the SKU Part Number”

    $ServicePlans = Get-MsolAccountSku | Where {$_.SkuPartNumber -eq “$SKN”}

    $ServicePlans.ServiceStatus

    $SKID = Read-Host “Please enter the SKU ID”

    $DLO = (Read-Host “Please enter the license options, separated by commas with no space”).Split(“,”)

    $MyO365Sku = New-MsolLicenseOptions -AccountSkuId $SKID -DisabledPlans $arrayDLO

    $UPN = Read-Host “Please enter the User Principal Name”

    Set-MsolUserLicense -UserPrincipalName $UPN -AddLicenses $SKID -LicenseOptions $MyO365Sku

  11. TPull avatar
    TPull

    I’m seeing an issue with this. The script runs successfully and I can see through the admin portal that my user was assigned the license. However, I’m still getting a warning for “Users with mailboxes but no licenses assigned”, even though the script assigned the Exchange Online license. Not until I open the user in the admin portal and click “Save” does the warning go away. It seems as though Set-MsolUserLicense isn’t doing whatever “Save” does in the web interface.

  12. Steve avatar
    Steve

    Thanks very much, Brian! Not sure how we would have ever figured this out.

    One note: in your original post i think you use “LicenceOptions” where the correct option is “LicenseOptions” (note the ‘c’ to a ‘s’). 😉

    thanks again!

  13. Brian Reid avatar

    @Steve, English UK (my language) changed to English US (Office 365 admin language). I think that is it for the regional errors now.

  14. Anonymous avatar
    Anonymous

    These are the service plans for the Academic A2 plans.

    SHAREPOINTWAC_EDU
    MCOSTANDARD
    SHAREPOINTSTANDARD_EDU
    EXCHANGE_S_STANDARD

  15. jreed336 avatar

    just ran through this. what we have found is that (at least with A2 licenses) you must assign the full license first. then go back and remove the serviceplans you do not want (separate commands). not sure why yet, but it’s the only way it’s working right now.

  16. Brian Reid avatar

    Here is the SKU for AADRM: RIGHTSMANAGEMENT_ADHOC
    And the Service Plan for the same is RMS_S_ADHOC

  17. Peter Nield avatar
    Peter Nield

    Hi,

    I was struggling with this, but I’ve found that when you create the New-MsolLicenseOptions, the disabled options parameter needs to be a array object, not just a comma separated list, e.g.

    Works when assigning license options:

    $LicOptions = New-MsolLicenseOptions -AccountSkuId “:STANDARDWOFFPACK_STUDENT” -DisabledPlans @(“SHAREPOINTWAC_EDU”,”MCOSTANDARD”,”SHAREPOINTSTANDARD_EDU”)

    Does not work when assigning license options:

    $LicOptions = New-MsolLicenseOptions -AccountSkuId “:STANDARDWOFFPACK_STUDENT” -DisabledPlans SHAREPOINTWAC_EDU, MCOSTANDARD, SHAREPOINTSTANDARD_EDU

    And the -LicenseOptions parameter for Set-MSOLUserLicense only works if:

    1. Modifying an license already assigned to the user.

    2. Adding the corresponding license in the same command.

Leave a Reply

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

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