Script Repository


Enable Microsoft 365 services based on Active Directory attribute

May 08, 2020
1111

The script enables or disables Microsoft 365 (Office 365) services for a user based on an attribute of the user's AD account. This can be used to specify which services exactly need to be enabled rather than specifying a list of assigned Microsoft 365 (Office 365) licenses.

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.

To manage Microsoft 365 (Office 365) services with the help of the script, you need to add an attribute for managing Microsoft 365 (Office 365) services to the Web interface page for editing users. For information on how to do that, see Customize Forms for User Creation and Editing, starting from step 6. The attribute must be multi-valued. For this purpose, you can use one of Adaxes virtual attributes, for example, CustomAttributeTextMultiValue1. They are not stored in AD, but can be used the same as any other attributes of AD objects.

To use the script in your environment, you need to create a Business Rule that runs the script after updating the attribute. Sample Business Rule:

Microsoft 365 (Office 365) services are enabled and disabled by adding and removing values from the multi-valued property. The added or removed value must contain the SKU part number of the Microsoft 365 (Office 365) license plan that the service belongs to and the SKU part number of the corresponding Microsoft 365 (Office 365) service. The SKU numbers must be separated by a semicolon (:) and included in brackets, for example:

Enterprise E3 - Exchange Online (ENTERPRISEPACK:EXCHANGE_S_ENTERPRISE)

For information on how to automatically populate a list of all available services as a drop-down list and avoid manual typing, see Automatically populate list of Microsoft 365 services as drop-down list.

For information on how to populate the attribute for users who already have certain Microsoft 365 (Office 365) services enabled, see Save enabled Microsoft 365 services to Active Directory attribute.

Parameter:

  • $enabledServicesProperty - specifies the LDAP name of the attribute that will be used for changing the list of services enabled for a user.
Edit Remove
PowerShell
$enabledServicesProperty = "adm-CustomAttributeTextMultiValue1" # TODO: modify me.

# Get object Id
try
{
    $objectId = [Guid]$Context.TargetObject.Get("adm-O365ObjectId")
}
catch
{
    return # The user doesn't have a Microsoft 365 account
}

# Get enabled service plans
try
{
    $enabledServicePlans = $Context.TargetObject.GetEx($enabledServicesProperty)
}
catch
{
    $enabledServicePlans = @()
}

$servicePlansToUpdate = @{}
foreach ($servicePlanInfo in $enabledServicePlans)
{
    $matchInfo = $servicePlanInfo | Select-String -Pattern "(?!.*\().+(?<!\))"
    $servicePlan = $matchInfo.Matches[0].Value
    $servicePlanIdentities = $servicePlan.Split(":")
    $skuPartNumber = $servicePlanIdentities[0]
    $servicePlanName = $servicePlanIdentities[1]

    if ($servicePlansToUpdate.ContainsKey($skuPartNumber))
    {
        $servicePlansToUpdate[$skuPartNumber] += $servicePlanName
    }
    else
    {
        [void]$servicePlansToUpdate.Add($skuPartNumber, @($servicePlanName))
    }
}

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

$scriptBlock = {
    param($microsoft365Cred, $objectId, $servicePlansToUpdate)
    Import-Module MsOnline
    
    # Connect to Microsoft 365
    Connect-MsolService -Credential $microsoft365Cred
    
    # Get Microsoft 365 user account
    $user = Get-MsolUser -ObjectId $objectId
    
    # Get assigned licenses
    $userLicenses = @{}
    $user.Licenses | %%{[void]$userLicenses.Add($_.AccountSku.SkuPartNumber, $_.AccountSkuId)}
    
    # Get all licenses
    $allLicenses = Get-MsolAccountSku

    foreach ($skuPartNumber in $servicePlansToUpdate.Keys)
    {
        $license = $allLicenses | where {$_.AccountSkuId.EndsWith($skuPartNumber)}
        if ($license -eq $NULL)
        {
            Write-Error "License '$skuPartNumber' was not found in Microsoft 365"
            continue
        }
    
        $allServicePlans = $license.ServiceStatus | %%{$_.ServicePlan.ServiceName}
        $servicePlanToUpdateNames = $servicePlansToUpdate[$skuPartNumber]
        $disabledPlans = @()

        foreach ($servicePlanName in $allServicePlans)
        {
            if ($servicePlanToUpdateNames -contains $servicePlanName)
            {
                continue
            }
    
            $disabledPlans += $servicePlanName
        }
        
        $licenseOptions = New-MsolLicenseOptions –AccountSkuId $license.AccountSkuId –DisabledPlans $disabledPlans
        try
        {
            if ($userLicenses.ContainsKey($skuPartNumber))
            {
                # The user already has the license assigned: update only
                Set-MsolUserLicense -ObjectId $objectId -LicenseOptions $licenseOptions -ErrorAction Stop
            }
            else
            {
                # Assign the license and specify the services to enable
                Set-MsolUserLicense -ObjectId $objectId -AddLicenses $license.AccountSkuId -LicenseOptions $licenseOptions -ErrorAction Stop
            }
        }
        catch
        {
            $errorMessage = "An error occurred when updating user licenses. Error: " + $_.Exception.Message
            Write-Error $errorMessage
        }

        [void]$userLicenses.Remove($skuPartNumber)
    }
    
    # Remove licenses that are not necessary any more
    foreach ($skuPartNumber in $userLicenses.Keys)
    {
        Set-MsolUserLicense -ObjectId $objectId -RemoveLicenses $userLicenses[$skuPartNumber]
    }
}

# Start Windows PowerShell as a separate process and run the script block in that process
$job = Start-Job -ScriptBlock $scriptBlock -ArgumentList $microsoft365Cred, $objectId.ToString(), $servicePlansToUpdate
$job | Wait-Job -Timeout 480
if ($job -eq $NULL)
{
    return
}

# Check whether there are any errors
$result = $job | Receive-Job
if ($result -ne $NULL)
{
    $Context.LogMessage($result, "Error")
}


Comments ( 0 )
No results found.
Leave a comment