<# .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 = 'acme103:ENTERPRISEPACK' EnabledPlans = 'EXCHANGE_S_ENTERPRISE' Group = 'E3-ExchangeOnline-Users' } 'E3-LyncO365ProPlus' = @{ LicenseSKU = 'acme103:ENTERPRISEPACK' EnabledPlans = 'MCOSTANDARD','OFFICESUBSCRIPTION' Group = 'E3-LyncO365ProPlus-Users' } 'E3' = @{ LicenseSKU = 'acme103: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 | Select-Object EmailAddress,@{Name="Licenses";Expression={(Get-MsolUser -UserPrincipalName $_.EmailAddress).Licenses }} | ForEach-Object -Process { if ($_.Licenses) { if ($EnabledPlans) { foreach ($plan in $EnabledPlans) { $ServiceStatus = ($_.Licenses.ServiceStatus | Where-Object {$_.ServicePlan.ServiceName -eq $plan}).Provisioningstatus switch ($servicestatus) { 'Disabled' { $AssignCustomLicense = $true } DEFAULT { $AssignCustomLicense = $false } } } } } [pscustomobject]@{ UserPrincipalName = $_.EmailAddress BaseLicense = $_.Licenses.AccountSkuID AssignCustomLicense = $AssignCustomLicense Licenses = $_.Licenses } } #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 | Where-Object {$_.BaseLicense -notcontains "$($AccountSKU.AccountSkuId)" -or $_.AssignCustomLicense}) { try { #Set UsageLocation Set-MsolUser -UserPrincipalName $User.UserPrincipalName -UsageLocation $UsageLocation -ErrorAction Stop -WarningAction Stop $LicenseConfig = @{ UserPrincipalName = $User.UserPrincipalName } if (($user.BaseLicense) -notcontains "$($AccountSKU.AccountSkuId)") { $LicenseConfig['AddLicenses'] = $AccountSKU.AccountSkuId } if ($EnabledPlans) { $CurrentPlans = (($user.Licenses | Where-Object {$_.AccountSkuid -eq "$($accountsku.AccountSkuId)"}).Servicestatus | Where-Object {$_.ProvisioningStatus -eq 'Success' -or $_.ProvisioningStatus -eq 'PendingInput'}).ServicePlan.ServiceName if ($CurrentPlans) { $ActualPlans = @() $ActualPlans += $CurrentPlans $ActualPlans += $EnabledPlans $LicenseOptions.DisabledServicePlans = ((Compare-Object -ReferenceObject $AccountSKU.ServiceStatus.ServicePlan.ServiceName -DifferenceObject $ActualPlans)).inputobject } $LicenseConfig['LicenseOptions'] = $LicenseOptions } Set-MsolUserLicense @LicenseConfig -ErrorAction Stop -WarningAction Stop Write-Output "SUCCESS: licensed $($User.UserPrincipalName) with $license" } catch { Write-Warning "Error when licensing $($User.UserPrincipalName)`r`n$_" } } }