Thursday, July 28, 2011

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_ServicePlan_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 ENTERPRISEPACK Sku:
  • OFFICESUBSCRIPTION (this is Office Professional Plus)
  • MCOSTANDARD (this is Lync)
  • SHAREPOINTWAC (this is Office Web Apps)
  • SHAREPOINTENTERPRISE
  • EXCHANGE_S_ENTERPRISE
Inside DESKLESSWOFFPACK Sku:
  • SHAREPOINTWAC
  • SHAREPOINTDESKLESS
  • EXCHANGE_S_DESKLESS
Inside EXCHANGEARCHIVE Sku
  • EXCHANGE_S_ARCHIVE
With thanks to Donte Henry (Avanade) and Tim Heeney (Microsoft). Discovered during the Office 365 MCM Class for Exchange 2010 MCM's.

13 comments:

Brian Reid said...

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

Justin Barker said...

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

MCOLITE
SHAREPOINTLITE
EXCHANGE_L_STANDARD

Hope this helps

Roman said...

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

Roman said...

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

Brian Reid said...

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

Roman said...

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

Roman said...

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.

Roman said...

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(",")

Brian Reid said...

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.

Roman said...

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

TPull said...

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.

Steve said...

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!

Brian Reid said...

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