Azure Active Directory Licensing

Microsoft has made significant strides with licensing options for Office 365. Licensing options can be found in the new Active Directory snap-in within Azure. This new snap-in allows organizations to control both licensing options and their associated services.

The Azure Active Directory snap-in can be accessed by following these steps:

  1. Login to https://portal.azure.com
  2. Select Azure Active Directory

  3. Under Manage, select Licenses

  4. Under Manage, select All products

  5. Select a license and click Assign

  6. Under Users and groups, select the user or group to assign the Office 365 license

  7. Under Assignment options, select the services you want to enable and disable

  8. Licensing reflects license assignments

More information on Azure Active Directory licensing in Azure can be found in the articles below.

https://docs.microsoft.com/en-us/azure/active-directory/active-directory-licensing-what-is

https://channel9.msdn.com/Series/Azure-Active-Directory-Videos-Demos/How-to-assign-Azure-AD-Premium-Licenses-to-user-accounts

https://docs.microsoft.com/en-us/azure/active-directory/active-directory-licensing-group-assignment-azure-portal

https://docs.microsoft.com/en-us/azure/active-directory/active-directory-licensing-group-migration-azure-portal

Background

Why do you need an Office 365 licensing script? The answer is twofold. First, the Office 365 license script is a set-it and forget-it tool. Any new service that is added to Office 365–and Microsoft is always adding new services–will be set to a disabled state for all users automatically the next time the script is executed. So, no interaction is needed from an administrative perspective.

Secondly, the Azure Active Directory snap-in does nothing for directly assigned licenses. Directly assigned licensing refers to administrators setting the license directly on a user, or group of users.

Our recommendation is to use the Office 365 licensing script along with the licensing option in Azure Active Directory. The Office 365 licensing script is part of the licensing solution. In many cases, Azure Active Directory will meet roughly 90% of your organization’s licensing needs. The Office 365 licensing script should fulfill the remaining 10%.

To illustrate how the Office 365 licensing script can support licensing features in Azure Active Directory, lets continue with the example above. I went into Janet’s account and directly assigned all services under E3 licenses to Janet’s account.

Note: You cannot disable any services that are assigned through licensing policies; you can only add new services.

The best way to set Janet’s account back to the deployed licensing option is via the Office 365 licensing script. Once the script has finished executing, licensing options will be set back for Janet’s account.

Solution

When configuring the licensing script to work within your organization, it is important to put the most restrictive AD group first in the script. By putting the most restrictive AD group first, if a user is a member of multiple security groups, that user would be assigned less restrictive licenses.

The following are requirements to run the Office 365 licensing script:

  • The path C:\temp\services\logs, needs to be created on the computer running the script
  • The first time running the script it will ask for the admin password. Once the password is provided, it will store the password in a secure file
  • The username needs to be changed to the admin account on line 3
  • Modify license information on lines 70 – 74
  • If you want to enable any other services, update line 10
  • To modify groups, edit lines 21 & 22. Groups should be those that are assigned licensing options within Azure Active Directory
  • The script will create a log file under C:\temp\services\Logs
  • The computer \ server must have the AD module installed

Note: If you want to use cloud groups instead of AD groups or want to use the Azure AD version of an AD group, please see Part 1 of the Office 365 licensing blog.

Current Licensing options for E3 as of 3/8/2017

  • Deskless
  • FLOW_O365_P2
  • TEAMS1
  • PROJECTWORKMANAGEMENT
  • SWAY
  • INTUNE_O365
  • YAMMER_ENTERPRISE
  • RMS_S_ENTERPRISE
  • MCOSTANDARD
  • EXCHANGE_S_ENTERPRISE
  • OFFICESUBSCRIPTION
  • SHAREPOINTWAC
  • SHAREPOINTENTERPRISE
  • POWERAPPS_O365_P2
  • OFFICESUBSCRIPTION

Results

Two Groups created within Active Directory. Each group only has one member, Christopher Crandall.

Since Christopher is a member of two groups, we want to place the most restrictive group first in the script. In our script, the E3-Limited group would be listed first.

The only services that should be enabled for Christopher’s account are Office Online, SharePoint, and PowerApps. The enabled apps can be changed by editing the service names listed in the code snip-it below.

Christopher’s account currently does not have any assigned licenses within Office 365.

Once the script is finished, Christopher will have EMS and limited services within E3.

From the log file, all the other Office 365 services have been set to a disabled state.


Script

$logfile = ("C:\temp\services\Logs\Services.log")
$logfile = ("C:\temp\services\Logs\Services.log") 
$PasswordFile = "C:\temp\Services\cred.txt"
$AdminAccount = "Admin@domain.com"

#E3 and EMS
$E3 = "CB5Lab:ENTERPRISEPACK"
$EMM = "CB5Lab:EMS"
$SKU = Get-MsolAccountSku | Where-Object {$_.AccountSkuID -eq $E3} 

$LicenseOption = New-Object System.Collections.ArrayList

$UsageLocation = 'US'

#E3 - All services
$PolicyE3 =  New-MsolLicenseOptions -AccountSkuId $E3 -DisabledPlans $Null

#EMM - All services
$PolicyEMM = New-MsolLicenseOptions -AccountSkuId $EMM -DisabledPlans $Null

#Groups
$Group1 = "E3-Limited"
$Group2 = "E3-EMM"

#GroupManagement
$Group1MemberShip = Get-ADGroupMember -identity $Group1 -Recursive | select SamAccountName
$Group2MemberShip = Get-ADGroupMember -identity $Group2 -Recursive | select SamAccountName


function log{
param (
[String]$text,
[Switch]$fout
)
ac $logfile $text
if($showConsoleOutput){
if($fout){
Write-Host $text -ForegroundColor Red
}else{
Write-Host $text -ForegroundColor Green
}
}
}
log -text "-----$(Get-Date) Services - $($env:USERNAME) on $($env:COMPUTERNAME) starting-----" 

$PasswordFileCheck = Test-Path $PasswordFile
If($PasswordFileCheck -eq $False){
Read-Host -Prompt "" -AsSecureString | ConvertFrom-SecureString | Out-File "C:\temp\services\cred.txt"
log -text "Created a password file under C:\temp\services"
}
Else{
log -text "Password file already created under C:\temp\services"
}

$Pass = Get-Content $PasswordFile | ConvertTo-SecureString
$Cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $AdminAccount, $Pass

Import-Module MSOnline
$Connect = Connect-MsolService -Credential $cred -ErrorAction SilentlyContinue -ErrorVariable ProcessError | ft '1' -HideTableHeaders

If ($ProcessError) {
log -text "------ Didn't Connect to Office 365 services"
}
Else{
log -text "Connect to Office 365 Services"}

$ServiceStatus = $SKU.ServiceStatus
Foreach ($item in $ServiceStatus) {
$Service = $Item.ServicePlan
$ServiceName = $Service.ServiceName
If ($ServiceName -eq "OFFICESUBSCRIPTION"){}
ElseIf ($ServiceName -eq "SHAREPOINTWAC"){}
ElseIf ($ServiceName -eq "SHAREPOINTENTERPRISE"){}
ElseIf ($ServiceName -eq "POWERAPPS_O365_P2"){}
ElseIf ($ServiceName -eq "OFFICESUBSCRIPTION  "){}
Else {
write-host $ServiceName
$TurnOffServices = $ServiceName
[void] $LicenseOption.Add("$TurnOffServices")
$PolicyE3Limited =  New-MsolLicenseOptions -AccountSkuId $E3 -DisabledPlans $LicenseOption 
}
}


Foreach ($Member in $Group1MemberShip){

$UPN = Get-ADUser -Identity $Member.SamAccountName | select UserPrincipalName

Foreach ($User in $UPN){
    $strUser = $user.UserPrincipalName | Out-String
    $strUser = $strUser.trim()
    #Write-host "This is the user account that will be changed $struser"
    Try{
    Set-MsolUser -UserPrincipalName $UPN.UserPrincipalName -UsageLocation $UsageLocation -ErrorAction Stop -WarningAction Stop
    Set-MsolUserLicense -UserPrincipalName $User.UserPrincipalName -AddLicenses $EMM -LicenseOptions $PolicyEMM -ErrorAction Stop
    log -text "User $strUser ------ License $EMM"
        }

    Catch {
    Set-MsolUserLicense -UserPrincipalName $User.UserPrincipalName -LicenseOptions $PolicyEMM 
    log -text "User $strUser ------ License Option $EMM"   
          }

    Try{
    Set-MsolUser -UserPrincipalName $UPN.UserPrincipalName -UsageLocation $UsageLocation -ErrorAction Stop -WarningAction Stop
    Set-MsolUserLicense -UserPrincipalName $User.UserPrincipalName -AddLicenses $E3 -LicenseOptions $PolicyE3Limited -ErrorAction Stop
    log -text "User $strUser ------ License $E3 ------- License Option $DisableServices"
        }

    Catch {
    Set-MsolUserLicense -UserPrincipalName $User.UserPrincipalName -LicenseOptions $PolicyE3Limited 
    log -text "User $strUser ------ License Option $DisableServices"   
          }
    
} 

}

Foreach ($Member in $Group2MemberShip){

$UPN = Get-ADUser -Identity $Member.SamAccountName | select UserPrincipalName

Foreach ($User in $UPN){
    $strUser = $user.UserPrincipalName | Out-String
    $strUser = $strUser.trim()
    #Write-host "This is the user account that will be changed $struser"
    Try{
    Set-MsolUserLicense -UserPrincipalName $User.UserPrincipalName -AddLicenses $EMM -LicenseOptions $PolicyEMM -ErrorAction Stop
    log -text "User $strUser ------ License $EMM"
        }

    Catch {
    Set-MsolUserLicense -UserPrincipalName $User.UserPrincipalName -LicenseOptions $PolicyEMM 
    log -text "User $strUser ------ License Option $EMM"   
          }

    Try{
    Set-MsolUserLicense -UserPrincipalName $User.UserPrincipalName -AddLicenses $E3 -LicenseOptions $PolicyE3 -ErrorAction Stop
    log -text "User $strUser ------ License $E3 ------- License Option $DisableServices"
        }

    Catch {
    Set-MsolUserLicense -UserPrincipalName $User.UserPrincipalName -LicenseOptions $PolicyE3 
    log -text "User $strUser ------ License Option $DisableServices"   
          }
}    
}