Script Repository


Activate Microsoft 365 services based on group membership

June 23, 2020
3074

The script assigns a Microsoft 365 (Office 365) license to a user and activates only specific services of the license depending on which group a user has been added to. To assign and revoke services with the help of the script, create a Business Rule triggering After adding or removing a member from a group and include the groups used for Microsoft 365 (Office 365) license assignment in its Activity Scope.

For the script to work, you need to install Microsoft Azure Active Directory Module for Windows PowerShell on each computer where Adaxes service is running.

Single Microsoft 365 (Office 365)License for All Groups

This version of the script assigns the same Microsoft 365 (Office 365) license to members of all groups. Groups differ only by the services enabled for their members.

Parameters:

  • $locationProperty - specifies a property of the user account that will be used as the user location in Microsoft 365 (Office 365). The value of the property must be represented by a two-letter country code per ISO 3166-1, for example, US or DE;
  • $licenseSku - specifies the SKU Part Number of the license that should be assigned to the user;
  • $groupInfo - specifies the Distinguished Names (DNs) of the groups and the corresponding services of the license represented by $licenseSku that should be activated for users when added to each group. Each service must be represented as the corresponding SKU Part Number.
  • $waitTime - specifies the time the script will wait for response from Microsoft 365 (Office 365). If a response is not received within the time specified, the operation will be completed asynchronously.
How to get the SKU Part Number of a license plan in Adaxes:
  1. In Adaxes Administration Console, expand the service node that represents your Adaxes service.
  2. Navigate to Configuration\Cloud Services and select Microsoft 365.
  3. Double-click the Microsoft 365 (Office 365) tenant to which the license belongs.
  4. Click the necessary license plan. The SKU Part Number is displayed below the Display Name field.
Edit Remove
PowerShell
$locationProperty = "c" # TODO: modify me
$licenseSku = "ENTERPRISEPACK" # TODO: modify me
$groupInfo = @{
    "CN=My group 1,OU=Groups,DC=domain,DC=com" = @("MCOSTANDARD", "SHAREPOINTENTERPRISE");
    "CN=My group 2,OU=Groups,DC=domain,DC=com" = @("EXCHANGE_S_ENTERPRISE");
} # TODO: modify me. Example $groupInfo = @{"<group distinguishedName>" = @("<service plan name>")}
$waitTime = 9 * 60 # TODO: modify me. Time in seconds

$scriptBlock = {
    param ($objectId, $licenseSku, $servicePlansToUpdate, $microsoft365Cred, $disableServicePlan)
    Import-Module MsOnline

    function SearchLicense($licenses, $skuPartNumber)
    {
        foreach ($license in $licenses)
        {
            if (!($license.AccountSkuId.EndsWith($skuPartNumber)))
            {
                continue
            }
            return $license
        }
        
        return $NULL
    }
    
    function UpdateLicense ($objectId, $licenseSku, $servicePlansToUpdate, $disableServicePlan, $updateAssignedLicense)
    {
        $disabledPlans = @()
        foreach ($servicePlan in $license.ServiceStatus)
        {
            if ($servicePlansToUpdate -contains $servicePlan.ServicePlan.ServiceName)
            {
                if ($disableServicePlan)
                {
                    $disabledPlans += $servicePlan.ServicePlan.ServiceName
                    continue
                }
                else
                {
                    continue
                }
            }
            
            if (($updateAssignedLicense) -and ($servicePlan.ProvisioningStatus -ne 'Disabled') -and ($servicePlan.ProvisioningStatus -ne 'None'))
            {
                continue
            }
            
            $disabledPlans += $servicePlan.ServicePlan.ServiceName
        }
        
        $disabledLicenses = New-MsolLicenseOptions –AccountSkuId $license.AccountSkuId –DisabledPlans $disabledPlans
        if ($updateAssignedLicense)
        {
            Set-MsolUserLicense -ObjectId $objectId -LicenseOptions $disabledLicenses
        }
        elseif ($disabledPlans.Length -eq $license.ServiceStatus.Count)
        {
            Set-MsolUserLicense -ObjectId $objectId -RemoveLicenses $license.AccountSkuId
        }
        else
        {
            Set-MsolUserLicense -ObjectId $objectId -AddLicenses $license.AccountSkuId -LicenseOptions $disabledLicenses
        }
    }
    
    # Connect to Microsoft 365
    Connect-MsolService -Credential $microsoft365Cred
    
    # Get licenses assigned to user
    $user = Get-MsolUser -ObjectId $objectId
    $license = $NULL
    $updateAssignedLicense = $True
    
    if ($user.isLicensed)
    {
        $license = SearchLicense $user.Licenses $licenseSku
    }
    
    if ($license -eq $NULL)
    {
        $licenses = Get-MsolAccountSku
        $license = SearchLicense $licenses $licenseSku
        $updateAssignedLicense = $False
    }
    
    UpdateLicense $objectId $license $servicePlansToUpdate $disableServicePlan $updateAssignedLicense
}

# Get service plans to update
$servicePlansToUpdate = $groupInfo["%distinguishedName%"]
if ($servicePlansToUpdate -eq $NULL)
{
    return
}

# Bind to member
$member = $Context.BindToObject("Adaxes://%member%")

# Get Microsoft 365 properties
$microsoft365Properties = $member.GetOffice365Properties()

# Check location
$microsoft365Location = $microsoft365Properties.Location
if ([System.String]::IsNullOrEmpty($microsoft365Location))
{
    # Get location from the specified property
    try
    {
        $location = $member.Get($locationProperty)
    }
    catch
    {
        $Context.LogMessage("Location not specified. Microsoft 365 account will not be activated", "Error")
        return
    }
    
    # Set location in Microsoft 365
    $microsoft365Properties.Location = $location
    
    # Save changes
    $member.SetOffice365Properties($microsoft365Properties)
    $member.SetInfo()
}

# Get Microsoft 365 Object ID
try
{
    $objectId = [Guid]$member.Get("adm-O365ObjectId")
    $objectId = $objectId.ToString()
}
catch
{
    $Context.LogMessage("The member doesn't have a Microsoft 365 account", "Warning")
    return
}

# Get Microsoft 365 tenant credentials
$microsoft365Cred = $Context.GetOffice365Credential()

# Check operation type
if ($Context.Action.IsOperationOfType($Context.TargetObject, "add group members"))
{
    $disableServicePlan = $False
}
else
{
    $disableServicePlan = $True
}

# Start Windows PowerShell as a separate process and run the script in that process
$job = Start-Job -ScriptBlock $scriptBlock -ArgumentList $objectId, $licenseSku, $servicePlansToUpdate, $microsoft365Cred, $disableServicePlan
Wait-Job -Job $job -Timeout $waitTime

if ($job.State -ne "Completed")
{
    return
}

# Get output from external process
Receive-Job -Job $job

Multiple Microsoft 365 (Office 365) Licenses

This version of the script assigns different Microsoft 365 (Office 365) licenses and services depending on the group.

Parameters:

  • $locationProperty - specifies a property of the user account that will be used as the user location in Microsoft 365 (Office 365). The value of the property must be represented by a two-letter country code per ISO 3166-1, for example, US or DE;
  • $groupInfo - specifies the Distinguished Names (DNs) of the groups, the corresponding Microsoft 365 (Office 365) license plans and services. The licenses and services must be represented by the corresponding SKU Part Number.
  • $waitTime - specifies the time the script will wait for response from Microsoft 365 (Office 365). If a response is not received within the time specified, the operation will be completed asynchronously.
How to get the SKU Part Number of a license plan in Adaxes:
  1. In Adaxes Administration Console, expand the service node that represents your Adaxes service.
  2. Navigate to Configuration\Cloud Services and select Office 365.
  3. Double-click the Microsoft 365 (Office 365) tenant to which the license belongs.
  4. Click the necessary license plan. The SKU Part Number is displayed below the Display Name field.
Edit Remove
PowerShell
$locationProperty = "c" # TODO: modify me
$groupInfo = @{
    "CN=My group 1,OU=Groups,DC=domain,DC=com" = @{
        "ENTERPRISEPACK" = @("MCOSTANDARD", "SHAREPOINTENTERPRISE")
        "ENTERPRISEPREMIUM" = @("YAMMER_ENTERPRISE")};
    "CN=My group 2,OU=Groups,DC=domain,DC=com" = @{
        "ENTERPRISEPACK" = @("EXCHANGE_S_ENTERPRISE")};
} # TODO: modify me. Example $groupInfo = @{"<group distinguishedName>" = @{"<license SKU 1>" = @("<service plan name>")}}
$waitTime = 9 * 60 # TODO: modify me. Time in seconds

$scriptBlock = {
    param ($objectId, $licenseInfo, $microsoft365Cred, $disableServicePlan)
    Import-Module MsOnline

    function SearchLicense($licenses, $skuPartNumber)
    {
        foreach ($license in $licenses)
        {
            if (!($license.AccountSkuId.EndsWith($skuPartNumber)))
            {
                continue
            }
            return $license
        }
        
        return $NULL
    }
    
    function UpdateLicense ($objectId, $licenseSku, $servicePlansToUpdate, $disableServicePlan, $updateAssignedLicense)
    {
        $disabledPlans = @()
        foreach ($servicePlan in $license.ServiceStatus)
        {
            if ($servicePlansToUpdate -contains $servicePlan.ServicePlan.ServiceName)
            {
                if ($disableServicePlan)
                {
                    $disabledPlans += $servicePlan.ServicePlan.ServiceName
                    continue
                }
                else
                {
                    continue
                }
            }

            if (($updateAssignedLicense) -and ($servicePlan.ProvisioningStatus -ne 'Disabled') -and ($servicePlan.ProvisioningStatus -ne 'None'))
            {
                continue
            }
            
            $disabledPlans += $servicePlan.ServicePlan.ServiceName
        }

        $disabledLicenses = New-MsolLicenseOptions –AccountSkuId $license.AccountSkuId –DisabledPlans $disabledPlans
        if ($updateAssignedLicense)
        {
            Set-MsolUserLicense -ObjectId $objectId -LicenseOptions $disabledLicenses
        }
        elseif ($disabledPlans.Length -eq $license.ServiceStatus.Count)
        {
            Set-MsolUserLicense -ObjectId $objectId -RemoveLicenses $license.AccountSkuId
        }
        else
        {
            Set-MsolUserLicense -ObjectId $objectId -AddLicenses $license.AccountSkuId -LicenseOptions $disabledLicenses
        }
    }
    
    # Connect to Microsoft 365
    Connect-MsolService -Credential $microsoft365Cred
    
    # Get user account in Microsoft 365
    $user = Get-MsolUser -ObjectId $objectId
    
    $allLicenses = Get-MsolAccountSku
    foreach ($licenseSku in $licenseInfo.Keys)
    {
        $license = SearchLicense $user.Licenses $licenseSku
        if ($license -eq $NULL)
        {
            $license = SearchLicense $allLicenses $licenseSku
            $updateAssignedLicense = $False
        }
        else
        {
            $updateAssignedLicense = $True
        }
        
        UpdateLicense $objectId $license $licenseInfo[$licenseSku] $disableServicePlan $updateAssignedLicense
    }
}

# Get licenses and service plans assigned to the group
$licenseInfo = $groupInfo["%distinguishedName%"]
if ($licenseInfo -eq $NULL)
{
    return
}

# Bind to member
$member = $Context.BindToObject("Adaxes://%member%")

# Get Microsoft 365 properties
$microsoft365Properties = $member.GetOffice365Properties()

# Check location
$microsoft365Location = $microsoft365Properties.Location
if ([System.String]::IsNullOrEmpty($microsoft365Location))
{
    # Get location from the specified property
    try
    {
        $location = $member.Get($locationProperty)
    }
    catch
    {
        $Context.LogMessage("Location not specified. Microsoft 365 account will not be activated", "Error")
        return
    }
    
    # Set location in Microsoft 365
    $microsoft365Properties.Location = $location
    
    # Save changes
    $member.SetOffice365Properties($microsoft365Properties)
    $member.SetInfo()
}

# Get Microsoft 365 Object ID
try
{
    $objectId = [Guid]$member.Get("adm-O365ObjectId")
    $objectId = $objectId.ToString()
}
catch
{
    $Context.LogMessage("The member doesn't have a Microsoft 365 account", "Warning")
    return
}

# Get Microsoft 365 tenant credentials
$microsoft365Cred = $Context.GetOffice365Credential()

# Check operation type
if ($Context.Action.IsOperationOfType($Context.TargetObject, "add group members"))
{
    $disableServicePlan = $False
}
else
{
    $disableServicePlan = $True
}

# Start Windows PowerShell as a separate process and run the script in that process
$job = Start-Job -ScriptBlock $scriptBlock -ArgumentList $objectId, $licenseInfo, $microsoft365Cred, $disableServicePlan
Wait-Job -Job $job -Timeout $waitTime

if ($job.State -ne "Completed")
{
    return
}

# Get output from external process
Receive-Job -Job $job


Comments ( 0 )
No results found.
Leave a comment