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 that can be used to register Microsoft 365 tenants.

To register a tenant, call the RegisterTenant method of the interface. The first parameter of the method specifies the ID of a Microsoft 365 account that will be used to perform operations within the new tenant. The ID consists of a Microsoft 365 user name and your Microsoft 365 domain name, for example, johndoe@example.onmicrosoft.com or johndoe@example.com. The account must be assigned either to the Global administrator or both the User administrator and Exchange administrator roles in Microsoft 365. The second parameter specifies the account password.

The return value of the method is an instance of the IAdmM365Tenant interface. You can use properties and methods of the interface to modify settings of the new tenant.

The following code sample registers a Microsoft 365 tenant.

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

$adminUserName = "someone@example.onmicrosoft.com"
$adminPassword = "secret"

$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
$tenant = $container.RegisterTenant($adminUserName, $adminPassword)
C#
using System;
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi.CloudServices.Office365;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;
class Program
{
    static void Main(string[] args)
    {
        const string adminUserName = "someone@example.onmicrosoft.com";
        const string adminPassword = "secret";

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

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

        // Register Tenant
        IAdmM365Tenant tenant = (IAdmM365Tenant)container.RegisterTenant(
            adminUserName, adminPassword);
    }
}

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.CloudServices.Office365;
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.CloudServices.Office365;
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.Interop.Adsi;
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi.CloudServices.Office365;
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 AdmO365AccountProperties 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 AdmO365AccountProperties class
$m365Props = New-Object `
    "Softerra.Adaxes.Adsi.CloudServices.Office365.AdmO365AccountProperties"

# 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.Office365;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;
using Softerra.Adaxes.Interop.Adsi.CloudServices.Office365;
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 AdmO365AccountProperties class
        AdmO365AccountProperties m365Props =
            new AdmO365AccountProperties();

        // 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.CloudServices.Office365;
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 AdmO365AccountProperties class
$m365Props = New-Object `
    "Softerra.Adaxes.Adsi.CloudServices.Office365.AdmO365AccountProperties"

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

# Save changes
$user.SetInfo()
C#
using Softerra.Adaxes.Interop.Adsi;
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi.CloudServices.Office365;
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 AdmO365AccountProperties class
        AdmO365AccountProperties m365Props =
            new AdmO365AccountProperties();

        // 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.CloudServices.Office365;
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 AdmO365AccountProperties class
$m365Props = New-Object `
    "Softerra.Adaxes.Adsi.CloudServices.Office365.AdmO365AccountProperties"

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

# Save changes
$user.SetInfo()
C#
using Softerra.Adaxes.Interop.Adsi;
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi.CloudServices.Office365;
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 AdmO365AccountProperties class
        AdmO365AccountProperties m365Props =
            new AdmO365AccountProperties();

        // 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