Managing Microsoft 365

Registering a tenant

Microsoft 365 tenants are stored as directory objects on Adaxes Configuration Server (AD LDS). To register a tenant, first, you need to bind to the container where Microsoft 365 tenants are stored using the following alias: "CloudServicesO365". The container implements the IAdmM365Container interface which provides methods for registering a Microsoft 365 tenant.

After binding to the container, create an instance of tenant credentials – call IAdmM365Container::CreateCredential and pass the desired credential type as a parameter. The available credential types are specified in ADM_M365TENANT_CREDTYPE_ENUM. The object returned by CreateCredential will implement a specific interface depending on the credential type.

Use its methods and properties to specify the credential details.

Then, call IAdmM365Container::CreateRegistrationParams to create the tenant registration parameters. The object returned by CreateRegistrationParams implements IAdmM365TenantRegistrationParams. Use its properties to configure the registration parameters.

Finally, call IAdmM365Container::RegisterTenant and pass your IAdmM365TenantRegistrationParams as the first parameter. The second parameter should be set to false.

The following code sample registers a Microsoft 365 tenant using an application account.

PowerShell
[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$applicationId = "e97b76b5-1e24-4d96-b251-1f938cb6459f"
$tenantId = "a5885e21-2ba8-4195-9a88-3756d1fe9023"
$clientSecret = "fK7--~yjs1fH8U9m5heb_VQyHBOybZlEOc"

# Connect to the Adaxes service
$ns = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
$service = $ns.GetServiceDirectly("localhost")

# Bind to the 'Microsoft 365' container
$containerPath = $service.Backend.GetConfigurationContainerPath("CloudServicesO365")
$container = $service.OpenObject($containerPath.ToString(),$null, $null, 0)

# Register tenant
$credential = $container.CreateCredential("ADM_M365TENANT_CREDTYPE_APPSECRET")
$credential.AppId = $applicationId
$credential.TenantId = $tenantId
$credential.SetSecret($clientSecret)

$parameters = $container.CreateRegistrationParams()
$parameters.Credential = $credential

$container.RegisterTenant($parameters, $false)
C#
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi.Microsoft365;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;

class Program
{
    static void Main(string[] args)
    {
        const string applicationId = "76bc664d-b6d1-41b6-b589-409416161c32";
        const string tenantId = "a5765e21-2ba8-4195-9a88-3756d1fe9453";
        const string clientSecret = "WIz6SBuc7-~1g6A-HJ7q~A8g04G66Q_5ep";

        // Connect to the Adaxes service
        AdmNamespace ns = new AdmNamespace();
        IAdmService service = ns.GetServiceDirectly("localhost");

        // Bind to the 'Microsoft 365' container
        string configurationContainerPath = service.Backend.GetConfigurationContainerPath(
            "CloudServicesO365");
        IAdmM365Container container = (IAdmM365Container)service.OpenObject(
            configurationContainerPath, null, null, 0);

        // Register tenant
        IAdmM365AppSecretTenantCredential credential =
            (IAdmM365AppSecretTenantCredential)container.CreateCredential(
                ADM_M365TENANT_CREDTYPE_ENUM.ADM_M365TENANT_CREDTYPE_APPSECRET);
        credential.AppId = applicationId;
        credential.TenantId = tenantId;
        credential.SetSecret(clientSecret);

        IAdmM365TenantRegistrationParams parameters = container.CreateRegistrationParams();
        parameters.Credential = credential;

        container.RegisterTenant(parameters, false);
    }
}

Modifying tenants

To modify a tenant, you need to bind to the directory object that represents the tenant at the Adaxes Configuration Server (AD LDS). To do this, first, you need to bind to the container where Microsoft 365 tenants are stored. The container supports the IADsContainer interface. You can use the interface to bind a particular tenant by name. To do so, call the GetObject method.

The first parameter of the method specifies the type of the directory object you want to bind to. The type of objects that represent Microsoft 365 tenants is adm-O365Tenant. As the second parameter, specify the tenant name preceded by the "CN=" prefix. For example, if you want to bind to a tenant called "My Tenant", specify the following string as the second parameter: "CN=My Tenant".

Each tenant object supports the IAdmM365Tenant interface that can be used to modify the tenant settings. To save the changes you make via the IAdmM365Tenant interface, call IADs::SetInfo.

The following code sample enables the Synchronize passwords option for a tenant.

PowerShell
[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$tenantName = "My Tenant"

# Connect to the Adaxes service
$ns = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
$service = $ns.GetServiceDirectly("localhost")

# Bind to the Microsoft 365 container
$containerPath = $service.Backend.GetConfigurationContainerPath("CloudServicesO365")
$container = $service.OpenObject($containerPath, $null, $null, 0)

# Bind to the Microsoft 365 tenant
$tenant = $container.GetObject("adm-O365Tenant", "CN=$tenantName")

# Synchronize passwords
$tenant.SynchronizePasswords = $true

# Save changes
$tenant.SetInfo()
C#
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi;
using Softerra.Adaxes.Interop.Adsi.Microsoft365;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;

class Program
{
    static void Main(string[] args)
    {
        const string tenantName = "My Tenant";

        // Connect to the Adaxes service
        AdmNamespace ns = new AdmNamespace();
        IAdmService service = ns.GetServiceDirectly("localhost");

        // Bind to the Microsoft 365 container
        string configurationContainerPath = service.Backend.GetConfigurationContainerPath(
            "CloudServicesO365");
        IADsContainer configurationContainer = (IADsContainer)service.OpenObject(
            configurationContainerPath, null, null, 0);

        // Bind to the Microsoft 365 tenant
        IAdmM365Tenant tenant = (IAdmM365Tenant)configurationContainer.GetObject(
            "adm-O365Tenant", "CN=" + tenantName);

        // Synchronize passwords
        tenant.SynchronizePasswords = true;

        // Save changes
        IAdmTop tenant2 = (IAdmTop)tenant;
        tenant2.SetInfo();
    }
}

Defining the associated directory scope

The scope of a tenant defines the part of your directory associated with it. The scope can include whole domains, members of groups and business units, objects located in specific organizational units, etc.

To modify the scope of a tenant, you need to use the IAdmM365Tenant interface. The AssociatedScopeItems property of the interface represents a collection of activity scope items that comprise the tenant scope. The property exposes the IAdmCollection interface, and each item in the collection supports the IAdmActivityScopeItem interface.

For more information on how to manage activity scope items, see Defining the scope of activity.

The following code sample includes a whole domain in the scope of a Microsoft 365 tenant.

PowerShell
[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$tenantName = "My Tenant"
$domainName = "example.com"

# Connect to the Adaxes service
$ns = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
$service = $ns.GetServiceDirectly("localhost")

# Bind to the Microsoft 365 container
$containerPath = $service.Backend.GetConfigurationContainerPath("CloudServicesO365")
$container = $service.OpenObject($containerPath, $null, $null, 0)

# Bind to the Microsoft 365 tenant
$tenant = $container.GetObject("adm-O365Tenant", "CN=$tenantName")

# Bind to the domain object
$domainObj = $service.OpenObject("Adaxes://$domainName", $null, $null, 0)

# Add the domain to the scope of the tenant
$scopeItem = $tenant.AssociatedScopeItems.Create()
$scopeItem.BaseObject = $domainObj
$scopeItem.Type = "ADM_SCOPEBASEOBJECTTYPE_CONTAINER"
$scopeItem.Inheritance = "ADS_SCOPE_SUBTREE"
$scopeItem.Exclude = $false
$scopeItem.SetInfo()
$tenant.AssociatedScopeItems.Add($scopeItem)
C#
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi;
using Softerra.Adaxes.Interop.Adsi.Microsoft365;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;

class Program
{
    static void Main(string[] args)
    {
        const string tenantName = "My Tenant";
        const string domainName = "example.com";

        // Connect to the Adaxes service
        AdmNamespace ns = new AdmNamespace();
        IAdmService service = ns.GetServiceDirectly("localhost");

        // Bind to the Microsoft 365 container
        string containerPath = service.Backend.GetConfigurationContainerPath(
            "CloudServicesO365");
        IADsContainer container = (IADsContainer)service.OpenObject(
            containerPath, null, null, 0);

        // Bind to the Microsoft 365 tenant
        IAdmM365Tenant tenant = (IAdmM365Tenant)container.GetObject(
            "adm-O365Tenant", "CN=" + tenantName);

        // Bind to the domain object
        IAdmTop domainObj = (IAdmTop)service.OpenObject("Adaxes://" + domainName,
            null, null, 0);

        // Add the domain to the scope of the tenant
        IAdmActivityScopeItem scopeItem =
            (IAdmActivityScopeItem)tenant.AssociatedScopeItems.Create();
        scopeItem.BaseObject = domainObj;
        scopeItem.Type =
            ADM_SCOPEBASEOBJECTTYPE_ENUM.ADM_SCOPEBASEOBJECTTYPE_CONTAINER;
        scopeItem.Inheritance = ADS_SCOPEENUM.ADS_SCOPE_SUBTREE;
        scopeItem.Exclude = false;
        scopeItem.SetInfo();
        tenant.AssociatedScopeItems.Add(scopeItem);
    }
}

Retrieving Microsoft 365 properties of users

To retrieve properties of a Microsoft 365 account of a user, you need to bind to the user object. Then, use the IAdmM365Account interface supported by user objects. To retrieve Microsoft 365 properties of the user, call the GetMicrosoft365Properties method of the interface.

Calling the GetMicrosoft365Properties method is expensive with regard to performance, as it fetches all information related to a user from Microsoft 365.

The following code sample outputs the status of the Sign In Blocked option for a user.

PowerShell
[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$ns = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
$service = $ns.GetServiceDirectly("localhost")

# Bind to user
$userDN = "CN=John Smith,CN=Users,DC=example,DC=com"
$user = $service.OpenObject("Adaxes://$userDN", $null, $null, 0)

# Retrieve properties of the Microsoft 365 account
$m365Props = $user.GetMicrosoft365Properties()

Write-Host "Sign in blocked:" $m365Props.SignInBlocked
C#
using System;
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi.Microsoft365;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;

class Program
{
    static void Main(string[] args)
    {
        AdmNamespace ns = new AdmNamespace();
        IAdmService service = ns.GetServiceDirectly("localhost");

        // Bind to user
        IAdmM365Account user = (IAdmM365Account)service.OpenObject(
            "Adaxes://CN=John Smith,CN=Users,DC=example,DC=com", null, null, 0);

        // Retrieve properties of the Microsoft 365 account
        IAdmM365AccountProperties m365Props = user.GetMicrosoft365Properties();

        bool signInBlocked = m365Props.SignInBlocked;
        Console.WriteLine("Sign in blocked: " + signInBlocked.ToString());
    }
}

Modifying Microsoft 365 properties of users

To perform operations on a Microsoft 365 account, first, you need to bind to the user object. All user objects support the IAdmM365Account interface. To modify Microsoft 365 properties of the user, call the SetMicrosoft365Properties method of the interface.

As the parameter of the SetMicrosoft365Properties method, you need to pass an instance of the IAdmM365AccountProperties interface that describes the modifications you want to make. To create a new instance of the interface, you can use the AdmM365AccountProperties class. Alternatively, you can call IAdmM365Account::GetMicrosoft365Properties to retrieve the current Microsoft 365 properties of the user.

Calling SetMicrosoft365Properties does not commit changes to Microsoft 365. To commit the changes, call IADs::SetInfo.

Activating Microsoft 365 accounts

To activate a Microsoft 365 account, you need to specify a location where the user will consume Microsoft 365 services. To specify a location, use the Location property of the IAdmM365AccountProperties interface. The value of the property must be represented by a two-letter country code as defined in ISO 3166-1 (e.g. US or DE).

The following code sample activates a Microsoft 365 account for a user and sets location in Microsoft 365 to United States.

PowerShell
[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$ns = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
$service = $ns.GetServiceDirectly("localhost")

# Bind to user
$userDN = "CN=John Smith,CN=Users,DC=example,DC=com"
$user = $service.OpenObject("Adaxes://$userDN", $null, $null, 0)

# Create a new instance of the AdmM365AccountProperties class
$m365Props = New-Object `
    "Softerra.Adaxes.Adsi.CloudServices.AdmM365AccountProperties"

# Set location to United States
$m365Props.Location = "US"
$user.SetMicrosoft365Properties($m365Props)

# Save changes
$user.SetInfo()
C#
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi;
using Softerra.Adaxes.Adsi.CloudServices;
using Softerra.Adaxes.Interop.Adsi.Microsoft365;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;

class Program
{
    static void Main(string[] args)
    {
        AdmNamespace ns = new AdmNamespace();
        IAdmService service = ns.GetServiceDirectly("localhost");

        // Bind to user
        IAdmM365Account user = (IAdmM365Account)service.OpenObject(
            "Adaxes://CN=John Smith,CN=Users,DC=example,DC=com", null, null, 0);

        // Create an instance of the AdmM365AccountProperties class
        AdmM365AccountProperties m365Props = new AdmM365AccountProperties();

        // Set location to United States
        m365Props.Location = "US";
        user.SetMicrosoft365Properties(m365Props);

        // Save changes
        IAdmTop user2 = (IAdmTop)user;
        user2.SetInfo();
    }
}

If the Synchronize passwords option is enabled for the Microsoft 365 tenant associated with the user, you can also set a password for the new Microsoft 365 account. For this purpose, use the InitialPassword property of the interface.

Assigning and revoking licenses

Prior to assigning or revoking licenses from users, you need to retrieve the current Microsoft 365 properties of the user account. To do this, call the GetMicrosoft365Properties method of the IAdmM365Account interface. The return value of the method is an instance of the IAdmM365AccountProperties interface that represents Microsoft 365 properties of the user. Use the Licenses property of the interface to assign and revoke licenses from the user.

The Licenses property gets an array of IAdmM365License interfaces. Each item in the array represents a Microsoft 365 license. To assign a license to a user, set the Assigned property of the interface to true. If you want to revoke a license, set the property to false.

The following code sample assigns all licenses available for a user.

PowerShell
[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$ns = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
$service = $ns.GetServiceDirectly("localhost")

# Bind to user
$userDN = "CN=John Smith,CN=Users,DC=example,DC=com"
$user = $service.OpenObject("Adaxes://$userDN", $null, $null, 0)

# Read Microsoft 365 properties
$m365Props = $user.GetMicrosoft365Properties()

# Assign all licenses
foreach ($license in $m365Props.Licenses)
{
    $license.Assigned = $true
}
$user.SetMicrosoft365Properties($m365Props)

# Save changes
$user.SetInfo()
C#
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi;
using Softerra.Adaxes.Interop.Adsi.Microsoft365;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;

class Program
{
    static void Main(string[] args)
    {
        AdmNamespace ns = new AdmNamespace();
        IAdmService service = ns.GetServiceDirectly("localhost");

        // Bind to user
        IAdmM365Account user = (IAdmM365Account)service.OpenObject(
            "Adaxes://CN=John Smith,CN=Users,DC=example,DC=com", null, null, 0);

        // Read Microsoft 365 properties
        IAdmM365AccountProperties m365Props = user.GetMicrosoft365Properties();

        // Assign all licenses
        foreach (IAdmM365License license in m365Props.Licenses)
        {
            license.Assigned = true;
        }
        user.SetMicrosoft365Properties(m365Props);

        // Save changes
        IAdmTop user2 = (IAdmTop)user;
        user2.SetInfo();
    }
}

A license will be assigned or revoked only if the AssignedModificationEnabled property of the IAdmM365License interface is set to true. When you modify the value of the Assigned property, the AssignedModificationEnabled property is set to true automatically.

To revoke all Microsoft 365 licenses from a user, set the RevokeAllLicenses property of the IAdmM365AccountProperties interface to true.

 Examples
PowerShell
[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$ns = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
$service = $ns.GetServiceDirectly("localhost")

# Bind to user
$userDN = "CN=John Smith,CN=Users,DC=example,DC=com"
$user = $service.OpenObject("Adaxes://$userDN", $null, $null, 0)

# Create a new instance of the AdmM365AccountProperties class
$m365Props = New-Object `
    "Softerra.Adaxes.Adsi.CloudServices.AdmM365AccountProperties"

# Revoke all licenses
$m365Props.RevokeAllLicenses = $true
$user.SetMicrosoft365Properties($m365Props)

# Save changes
$user.SetInfo()
C#
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi;
using Softerra.Adaxes.Adsi.CloudServices;
using Softerra.Adaxes.Interop.Adsi.Microsoft365;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;

class Program
{
    static void Main(string[] args)
    {
        AdmNamespace ns = new AdmNamespace();
        IAdmService service = ns.GetServiceDirectly("localhost");

        // Bind to user
        IAdmM365Account user = (IAdmM365Account)service.OpenObject(
            "Adaxes://CN=John Smith,CN=Users,DC=example,DC=com", null, null, 0);

        // Create an instance of the AdmM365AccountProperties class
        AdmM365AccountProperties m365Props = new AdmM365AccountProperties();

        // Revoke all licenses
        m365Props.RevokeAllLicenses = true;
        user.SetMicrosoft365Properties(m365Props);

        // Save changes
        IAdmTop user2 = (IAdmTop)user;
        user2.SetInfo();
    }
}

To assign or revoke a specific license, you need to identify which of the IAdmM365License interfaces available in the Licenses property represents the license you need. To do so, you can use the Sku property of the IAdmM365License interface. The property gets the IAdmM365SkuInfo interface that can be used to retrieve information about a license plan associated with the license. For example, using the SkuPartNumber property of the interface, you can get the name of the license plan in Microsoft 365.

After identifying the necessary IAdmM365License interface, modify the value of the Assigned property of the interface to assign or revoke the license.

The following code sample revokes a license for a specific license plan.

PowerShell
[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$planName = "ENTERPRISEPACK" # Microsoft 365 Enterprise E3

$ns = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
$service = $ns.GetServiceDirectly("localhost")

# Bind to user
$userDN = "CN=John Smith,CN=Users,DC=example,DC=com"
$user = $service.OpenObject("Adaxes://$userDN", $null, $null, 0)

# Read Microsoft 365 properties
$m365Props = $user.GetMicrosoft365Properties()

# Revoke the license
foreach ($license in $m365Props.Licenses)
{
    if ($license.Sku.SkuPartNumber -eq $planName)
    {
        $license.Assigned = $false
        break
    }
}
$user.SetMicrosoft365Properties($m365Props)

# Save changes
$user.SetInfo()
C#
using System;
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi;
using Softerra.Adaxes.Interop.Adsi.Microsoft365;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;

class Program
{
    static void Main(string[] args)
    {
        const string planName = "ENTERPRISEPACK"; // Microsoft 365 Enterprise E3

        AdmNamespace ns = new AdmNamespace();
        IAdmService service = ns.GetServiceDirectly("localhost");

        // Bind to user
        IAdmM365Account user = (IAdmM365Account)service.OpenObject(
            "Adaxes://CN=John Smith,CN=Users,DC=example,DC=com", null, null, 0);

        // Read Microsoft 365 properties
        IAdmM365AccountProperties m365Props = user.GetMicrosoft365Properties();

        // Revoke the license
        foreach (IAdmM365License license in m365Props.Licenses)
        {
            if (StringComparer.OrdinalIgnoreCase.Equals(
                license.Sku.SkuPartNumber, planName))
            {
                license.Assigned = false;
                break;
            }
        }
        user.SetMicrosoft365Properties(m365Props);

        // Save changes
        IAdmTop user2 = (IAdmTop)user;
        user2.SetInfo();
    }
}

Deactivating Microsoft 365 accounts

To deactivate a Microsoft 365 account of a user and block user access to Microsoft 365 services, you need to set the SignInBlocked property of the IAdmM365AccountProperties interface to true.

The following code sample deactivates a Microsoft 365 account for a user.

PowerShell
[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$ns = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
$service = $ns.GetServiceDirectly("localhost")

# Bind to user
$userDN = "CN=John Smith,CN=Users,DC=example,DC=com"
$user = $service.OpenObject("Adaxes://$userDN", $null, $null, 0)

# Create a new instance of the AdmM365AccountProperties class
$m365Props = New-Object "Softerra.Adaxes.Adsi.CloudServices.AdmM365AccountProperties"

# Block Access to Microsoft 365 services
$m365Props.SignInBlocked = $true
$user.SetMicrosoft365Properties($m365Props)

# Save changes
$user.SetInfo()
C#
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi;
using Softerra.Adaxes.Adsi.CloudServices;
using Softerra.Adaxes.Interop.Adsi.Microsoft365;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;

class Program
{
    static void Main(string[] args)
    {
        AdmNamespace ns = new AdmNamespace();
        IAdmService service = ns.GetServiceDirectly("localhost");

        // Bind to user
        IAdmM365Account user = (IAdmM365Account)service.OpenObject(
            "Adaxes://CN=John Smith,CN=Users,DC=example,DC=com", null, null, 0);

        // Create an instance of the AdmM365AccountProperties class
        AdmM365AccountProperties m365Props = new AdmM365AccountProperties();

        // Block Access to Microsoft 365 services
        m365Props.SignInBlocked = true;
        user.SetMicrosoft365Properties(m365Props);

        // Save changes
        IAdmTop user2 = (IAdmTop)user;
        user2.SetInfo();
    }
}

Apart from Microsoft 365 user account management, you can also manage Exchange Online mailboxes. For more information, see Performing Exchange tasks

See also