Tag Archives: Add Office 365 Licenses Groups

Office 365: Assign individual parts of licenses based on groups using PowerShell

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 story continues… After numerous requests regarding handling parts of licenses in my older licensing scripts , I’ve now created an example on how to do this using security groups.

Please note that this is of course not a complete solution, just an example on how to incorporate this in to one of the earlier solutions created.

SCENARIO
In this example, I will have three groups each assigning different parts of an E3 License. One assiging the Full E3, one assigning Exchange Online and one assigning Lync Online + Office 365 ProPlus.
In order to assign them with PowerShell, we need the ServicePlan name of each part we want to assign. Those can be found with the following command for an E3-license:

(Get-MsolAccountSku | Where-Object {$_.SkuPartNumber -eq "ENTERPRISEPACK"}).ServiceStatus

2014-12-16_20-32-02
As seen above the names are pretty easy to recognise, if you are unsure which one is which, you will find a good translation table here.

Disabling plans with PowerShell requires you to to select the ones that you want to disable rather than the ones you want to enable, just like in the portal. In my example I’m choosing the parts I want to assign per group, which means I’m disabling all other parts than just the ones you want.
See the example below how I’ve configured my $Licenses hashtable for my scenario:

$Licenses = @{
                 'E3-ExchangeOnline' = @{
                          LicenseSKU = 'tenant:ENTERPRISEPACK'
                          EnabledPlans = 'EXCHANGE_S_ENTERPRISE'
                          Group = 'E3-ExchangeOnline-Users'
                        }
                 'E3-LyncO365ProPlus' = @{
                          LicenseSKU = 'tenant:ENTERPRISEPACK'
                          EnabledPlans = 'MCOSTANDARD','OFFICESUBSCRIPTION'
                          Group = 'E3-LyncO365ProPlus-Users'
                        }
                 'E3' = @{
                          LicenseSKU = 'tenant:ENTERPRISEPACK'
                          Group = 'E3-Users'
                        }
            }

RUNNING THE SCRIPT
After editing the $Licenses hashtable, $UsageLocation and tenant credentials, you’re ready to run the script as in the screenshot below.
2014-12-16_21-52-24

2014-12-16_21-40-47
A user that have been assigned licenses with the E3-LyncO365ProPlus-Users group in the example

LicenseO365Users.ps1

<# .SYNOPSIS     Script that assigns Office 365 licenses based on Group membership in AAD. .NOTES     Author: Johan Dahlbom      Blog: 365lab.net      Email: johan[at]dahlbom.eu      The script are provided “AS IS” with no guarantees, no warranties, and they confer no rights.     Requires PowerShell Version 3.0! #>

#Import Required PowerShell Modules
Import-Module MSOnline
#Office 365 Admin Credentials
$CloudUsername = 'admin@tenant.onmicrosoft.com'
$CloudPassword = ConvertTo-SecureString 'password' -AsPlainText -Force
$CloudCred = New-Object System.Management.Automation.PSCredential $CloudUsername, $CloudPassword
#Connect to Office 365
Connect-MsolService -Credential $CloudCred
$UsageLocation = 'SE'

$Licenses = @{
                 'E3-ExchangeOnline' = @{
                          LicenseSKU = 'tenant:ENTERPRISEPACK'
                          EnabledPlans = 'EXCHANGE_S_ENTERPRISE'
                          Group = 'E3-ExchangeOnline-Users'
                        }
                 'E3-LyncO365ProPlus' = @{
                          LicenseSKU = 'tenant:ENTERPRISEPACK'
                          EnabledPlans = 'MCOSTANDARD','OFFICESUBSCRIPTION'
                          Group = 'E3-LyncO365ProPlus-Users'
                        }
                 'E3' = @{
                          LicenseSKU = 'tenant:ENTERPRISEPACK'
                          Group = 'E3-Users'
                        }
            }

foreach ($license in $Licenses.Keys) {
    $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"

    #region Disable non specific plans
    $EnabledPlans = $Licenses[$license].EnabledPlans
    if ($EnabledPlans) {
        $LicenseOptionHt = @{
            AccountSkuId = $AccountSKU.AccountSkuId
            DisabledPlans =  (Compare-Object -ReferenceObject $AccountSKU.ServiceStatus.ServicePlan.ServiceName -DifferenceObject $EnabledPlans).InputObject
        }
        $LicenseOptions = New-MsolLicenseOptions @LicenseOptionHt
    }
    #endregion Disable non specific plans

    #Get all unlicensed group members - needs to be changed if a user should be able to have more than one license
    $GroupMembers = (Get-MsolGroupMember -GroupObjectId $GroupID -All | Where-Object {$_.IsLicensed -eq $false}).EmailAddress
    #Warn if not enough licenses are available
    if ($AccountSKU.ActiveUnits - $AccountSKU.consumedunits -lt $GroupMembers.Count) {
        Write-Warning 'Not enough licenses for all users, please remove user licenses or buy more licenses'
    }

    foreach ($User in $GroupMembers) {
        try {
            #Set UsageLocation
            Set-MsolUser -UserPrincipalName $User -UsageLocation $UsageLocation -ErrorAction Stop -WarningAction Stop
            $LicenseConfig = @{
                UserPrincipalName = $User
                AddLicenses = $AccountSKU.AccountSkuId
            }
            if ($EnabledPlans) {
                $LicenseConfig['LicenseOptions'] = $LicenseOptions
            }
            Set-MsolUserLicense @LicenseConfig -ErrorAction Stop -WarningAction Stop
            Write-Output "SUCCESS: licensed $User with $license"
        } catch {
            Write-Warning "Error when licensing $User`r`n$_"
        }
    }
 }

Let me know if you have any questions or feedback!

/Johan

Advertisements