Working with a client to ease the transition of Office 2010 (MSI) using KMS licensing to Office 2013/2016 (Click-to-Run) with subscription licensing to use the new Skype for Business client. It quickly became apparent that enabling thousands of globally dispersed users for a certain feature set via Office 365 Admin Portal wasn’t going to work. PowerShell always to the rescue!
Script Download: BulkO365LicenseServices.ps1 https://gallery.technet.microsoft.com/Bulk-provisioning-Office-f64747d5
First, we have some prerequisites to connect to Microsoft Online and Active Directory(AD) via PowerShell:
- Install and Connect to Azure AD (
https://technet.microsoft.com/library/jj151815.aspx)
- 64-Bit Operating System
- Microsoft Online Services Sign-In Assistant for IT Professionals RTW (64-bit): https://www.microsoft.com/en-us/download/details.aspx?id=41950
- Latest Azure Active Directory Module for PowerShell: https://bposast.vo.msecnd.net/MSOPMW/Current/amd64/AdministrationConfig-en.msi
- User account assigned to the Global admin or User management admin role in Office 365
- AD PowerShell module is part of the Remote Server Administration Tools (RSAT):
- RSAT for Windows 7: https://www.microsoft.com/en-us/download/details.aspx?id=7887
- RSAT for Windows 8: https://www.microsoft.com/en-us/download/details.aspx?id=28972
- RSAT for Windows 10: https://www.microsoft.com/en-ca/download/details.aspx?id=45520
- Windows Server 2008R2, 2012, 2012R2: AD module for PowerShell is found under the Remote Sever Administration Tools in the Add Features
The following is a breakdown of the core logic in my script, minus the reporting, error handling and loops…
Load required modules and test connectivity.
Import-Module ActiveDirectory
Import-Module MSOnline
Connect-MsolService #Sign in using account with appropriate licensing permissions
Get-MsolDomain
Figure out the Account SKUs associated to the Office 365 Tenant, available licenses and the specific services to choose from. The most complete list I’ve found for the breakdown of services for each SKU can be found at: http://blogs.technet.com/b/treycarlee/archive/2013/11/01/list-of-powershell-licensing-sku-s-for-office-365.asp (don’t forget to check the comments).
Get-MsolAccountSku | %{$_.accountskuID;Write "Remaining Licenses:";($x =$_.ActiveUnits - $_.ConsumedUnits);$_.ServiceStatus|ft -hide}
It’s counterintuitive, but when applying specific Office 365 services from PowerShell you apply a list of services you want disabled vs. the services you want.
The easiest way to figure out which services to disable or enable is to configure a single account using the Office 365 Admin Portal and review via PowerShell.
Get-MsolUser -UserPrincipalName test2@lamontagnesolutions.com |%{ $_.licenses.servicestatus}
Make sure your licensing script takes into account when Microsoft changes or adds a new service. You’ll need a way of comparing enable services to available services, giving a disabled list.
#AccountSKU to use
$AccountSKUID = "LaMSol:ENTERPRISEPACK"
#list of Enabled services
$SubLicense = ("RMS_S_ENTERPRISE","OFFICESUBSCRIPTION","MCOSTANDARD","SHAREPOINTWAC","SHAREPOINTENTERPRISE")
get-msolaccountsku | Where {$_.accountSkuID -eq $AccountSKUID } | Select -expand "ServiceStatus" | select -expand "ServicePlan" | select ServiceName | Where {$SubLicense -notcontains $_.ServiceName}
Grab users and additional attributes based on AD OU.
#User OU's distinguishedName attribute
$OUsearch = "DC=lamontagnesolutions,DC=com"
get-aduser -Filter * -Searchbase $OUsearch -properties mail,Country| ?{ $_.Enabled -eq 'True'} |Ft name,userprincipalname,mail,country
Search for Microsoft Online user using either the mail or userprincipalname attribute as the cloud User Principal Name (UPN).
#Using user's Active Directory Mail attribute to find MSOl User.
$upn = (get-aduser Test2 -Properties mail).mail
#To use UserPrincipalName instead to find MSOl User:
#$upn = (get-aduser Test2).UserPrincipalName
Get-MsolUser -UserPrincipalName $upn
Is the user licensed for the specific Account SKU?
Get-MsolUser -UserPrincipalName test2@lamontagnesolutions.com | ?{ $_.isLicensed -eq "TRUE" } | ?{ ($_.Licenses | ?{ $_.AccountSkuId -eq $AccountSKUID}).Length -gt 0}
If the user is already licensed for the specific Account SKU, confirm/enable required services. Don’t disable additional enabled services as these might be pilot users.
$disabledServices = (Get-MsolUser -UserPrincipalName test2@lamontagnesolutions.com).Licenses.servicestatus | where {$_.ProvisioningStatus -eq "Disabled"} | select -expand serviceplan | Select ServiceName
$disabledServices = $disabledServices | where {$SubLicense -notcontains $_.ServiceName}
$disabled = @()
foreach ($item in $disabledServices.servicename) {$disabled += $item}
$LicenseOptions = New-MsolLicenseOptions -AccountSkuId $AccountSKUID -DisabledPlans $disabled
set-msoluserlicense -userprincipalname test2@lamontagnesolutions.com -licenseoptions $LicenseOptions
If the user isn’t licensed, set location based on AD country attribute or manual country code then add Account SKU with required services.
$Location = (get-aduser Test1 -Properties country).country
#$Location = "CA"
$disabledServices = get-msolaccountsku | Where {$_.accountSkuID -eq $AccountSKUID } | Select -expand "ServiceStatus" | select -expand "ServicePlan" | select ServiceName | Where {$SubLicense -notcontains $_.ServiceName}
$disabled = @()
foreach ($item in $disabledServices.servicename) {$disabled += $item}
$LicenseOptions = New-MsolLicenseOptions -AccountSkuId $AccountSKUID -DisabledPlans $Disabled
Set-MsolUser -UserPrincipalName test1@lamontagnesolutions.com –UsageLocation $Location
Set-MsolUserLicense -User test1@lamontagnesolutions.com -AddLicenses $AccountSKUID -LicenseOptions $LicenseOptions
Download: BulkO365LicenseServices.ps1 https://gallery.technet.microsoft.com/Bulk-provisioning-Office-f64747d5