Azure/O365 connector

General information

The Azure connector allows OpenIAM to manage objects inside Azure AD – users, groups, memberships and license assignment. It also allows us to manage O365.

Microsoft Azure provides various services in the cloud that are analogous to on-premise ones. If you need to manage identities of some particular service, please refer to the appropriate connector. For example, for managing Exchange mailboxes either on-premise or online you have to use the Exchange connector.

Service account information:

During Managed System configuration inside the OpenIAM /webconsole section you should set the Login ID, which will be used as a service account for OpenIAM.

Please note that the service account should be set as a primary account address that has email format. For example, 'serviceaccount@openiamdemo.com'

The Service account you use should have rights to create users in Azure, modify their properties and perform any actions that you would like the connector to do.

Requirements

  • .NET 4.7.2 or above (requirement of Az module)
  • PowerShell Azure connector works with PowerShell 5.1 or PowerShell 6.
  • For Windows 8.1, Windows 8, Windows 7 Service Pack 1 (SP1), Windows Server 2012 R2, Windows Server 2012, and Windows Server 2008 R2 SP1, download and install the Windows Management Framework 5.1.

In addition to general connector requirements described in the "PowerShell connector usage" document, the Azure connector relies on following modules:

  • MSOnline
  • AzureAD
  • Az

To verify if you have the MSOnline module installed, please start the PowerShell console (please make sure that you are running x64 console) and run the following command:

Import-Module MSOnline

If you do not see any errors and you receive an empty output, you already have the MSOnline module installed and you can proceed to checking the next dependency. However, if this module is not installed, you would see an error that looks similar to:

No MSOnline module installed

In this case you need to install this module by running (using x64 PowerShell console):

Install-Module MSOnline

You will need to agree on the installation by pressing 'Y' as a confirmation.

Note - if installation using the command above causes errors, most probably you are not using TLS 1.2. Microsoft enforced it to be default protocol for downloading NuGet packages, however, it does not go by default in some of the PowerShell sessions. To switch to TLS 1.2 you should run first:

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

After that you can proceed installing modules.

When you checked that the MSOnline module is installed you need to make sure that the AzureAD module is available as well.

Get-InstalledModule -Name AzureAD

Again, if you see an error after running the command above, you should install this module using:

Install-Module -Name AzureAD

Checking if Az module is installed:

Get-InstalledModule -Name Az

If the module is not installed, you should install it:

Install-Module -Name Az

Installation and connection to OpenIAM

All PowerShell connectors are installed in the same way, which is described in the document: PowerShell connector installation

General usage

All PowerShell connectors are used in the same way, which is described in the document: PowerShell connector usage

Connecting to your directory

To connect OpenIAM to the Azure/O365 service using the connector you need to specify the service account on the Manageed System configuration page. This service account should have sufficient privileges to perform actions that you would like to do using PowerShell connector.

No MSOnline module installed

Define attribute provisioning rules

The Azure/O365 PowerShell connector supports working with the following identities:

  • Users
  • Groups (Security, Distribution (Exchange online), MailEnabledSecurity, Office365)

User provisioning

Principal - UserPrincipalName

NB! It is required on the Microsoft side that during user creation we specify DisplayName and Usage Location for the new user. If those parameters are not set the DisplayName will be set the same as UserPrincipalName and UsageLocation – ‘US’ by default. You can override those settings by sending attributes with appropriate names.

You can specify following attributes inside the policy map.

ParameterDescriptionRequiredValues
UserPrincipalNameSpecifies the user ID for this user. This is required.YesString in UPN format
AlternateEmailAddressesSpecifies alternate email addresses for the user. Please note that though this parameter sounds plural, Microsoft currently allows only one alternate email address. This parameter is intended for admin users and serves as a password recovery feature if the admin forgets his/her password and is not normally used for regular users.NoString in UPN format
AlternateMobilePhonesSpecifies alternate mobile phone numbers for the user.NoString or comma separated string
BlockCredentialSpecifies whether the user is not able to log on using their user ID.NoTrue or False
CitySpecifies the city of the user.NoString
CountrySpecifies the country or region of the user.NoString
DepartmentSpecifies the department of the user.NoString
DisplayNameSpecifies the display name of the user.NoString
FaxSpecifies the fax number of the user.NoString
FirstNameSpecifies the first name of the user.NoString
ImmutableIDSpecifies the immutable ID of the federated identity of the user. This should be omitted for users with standard identities.NoString
LastNameSpecifies the last name of the user.NoString
LicensesToAssignJsonContains information about licenses that need to be assigned for the current user. Detailed explanation about the format of this parameter is given next to this table.NoString
LicensesToRemoveJsonContains information about licenses that need to be removed from the current user. Please note, that this parameter is executed before ‘LicensesToAssignJson’. Detailed explanation about the format of this parameter is given next to this table.NoString
MobilePhoneSpecifies the mobile phone number of the user.NoString
OfficeSpecifies the office of the user.NoString
PasswordSpecifies the new password for the user. If the user is set to require a strong password, then all of the following rules must be met: The password must contain at least one lowercase letter; The password must contain at least one uppercase letter; The password must contain at least one non-alphanumeric character; The password cannot contain any spaces, tabs, or line breaks; The length of the password must be 8-16 characters; The user name cannot be contained in the password; If this value is omitted, then a random password is assigned to the user.NoString
PhoneNumberSpecifies the phone number of the user.NoString
PostalCodeSpecifies the postal code of the user.NoString
PreferredDataLocationSpecifies the preferred data location for the user. The following value could be used (Name – Value for this location): Asia Pacific=APC; Australia=AUS; Canada=CAN; European Union=EUR; France=FRA; India=IND; Japan=JPN; Korea=KOR; United Kingdom=GBR; United States=NAM; Actual locations could be found in Microsoft documentation. If an invalid value is set the default location would be used. The India geo is only available to customers with billing address and licenses purchased in this geo. Not all Office 365 workloads support the use of setting a user's geo.NoString
StateSpecifies the state or province where the user is located.NoString
StreetAddressSpecifies the street address of the user.NoString
StrongPasswordRequiredSpecifies whether to require a strong password for the user.NoTrue or False
TitleSpecifies the title of the user.NoString
UsageLocationSpecifies the location of the user where services are consumed. Specify a two-letter country code.NoString
UserTypeSpecifies the user type. One of Microsoft.Online.Administration.UserType values. Example: Guest, MemberNoString

Working with license parameters

The connector is capable of setting any subset of licenses inside the global plan. For example:

Licensing parameters

The connector can assign a whole license pack (like E1, E3 etc.) and also supports partial licensing (for example, assigning E1 with some features disabled).

To assign the license the connector should receive attribute 'LicensesToAssignJson', and for license removal 'LicensesToRemoveJson'.

If set, removing licenses will be executed before assigning by connector (because some of the licenses cannot coexist, for example E1 and E3).

Handling license assignment - LicensesToAssignJson uses the following format:

License assignment JSON

Example: [{"LicenseName":"openiamdemocloud:ENTERPRISEPACK","DisabledPlans":["SWAY","FLOW_O365_P2"]},{"LicenseName":"openiamdemocloud:POWER_BI_STANDARD","DisabledPlans":["BI_AZURE_P0"]}]

In this example, we are setting the E3 license with disabled SWAY and FLOW_O365_P2 and PowerBI license with disabled BI_AZURE_P0. License name is specific to your organization, as you can see it starts with an organization name prefix and ends with the license name. If you are not sure what license names your organization has, you can run the following commands and they will show available license names that could be applied in parameter above.

Connect-MsolService
Get-MsolAccountSku

If you need to keep the whole package enabled you should leave DisabledPlan as an empty array ([]).

If you currently have one set of disabled plans and you need to enable them but disabled another other set of plans, you just set the final list that should be disabled to the DisabledPlans and all plans that belong to the package but not listed there will be enabled.

Handling license removal: - LicensesToRemoveJson uses the following format:

License removal JSON

Example: [{"LicenseName":"openiamdemocloud:STANDARDPACK"},{"LicenseName":"openiamdemocloud:POWER_BI_STANDARD"}]

In this example, we are removing the E1 and PowerBI licenses completely. Please note that this attribute is responsible for complete license removal. In case you need to disable just several plans of the license please use the LicensesToAssignJson attribute with DisabledPlan array.

Synchronization

Working with reconciliation and synchronization is described in a separate document. In addition to specifying appropriate groovy scripts for transformation/validation rules, you should also set a search string at the 'SQL Query / Directory Filter' parameter of your sycnhronization page (Webconsole -> Top menu 'Provisioning' -> Synchronization -> Edit your synchronization profile). That string is the actual request that will be executed by the connector to find/filter users or groups from Azure.

Users synchronization

For running Azure users synchronization you can use variations of the Get-MSOLUser query. Some usage examples are below.

This query gets all users with all properties that are available.

Get-MSOLUser -All | Select-Object *

The query below selects all data about one particular user by sign-in name. Let's call this user 'someUser@openiam.com':

Get-MSOLUser -SearchString 'someUser@openiam.com' | Select-Object *

The query below gets one random first user (usually useful for tests):

Get-MSOLUser -MaxResults 1 | Select-Object *

Sometimes you may neeed to get information about several users. For example, below we get data about users with giden ObjectIDs:

Get-MSOLUser -All | Where-Object {​​​​​​​​ $_.ObjectID -eq '6e40cdcd-c066-4c38-8052-bf44a2322632' -or $_.ObjectID -eq 'ac9b7019-c026-403b-b3ee-231b6b5453b5'}​​​​​​​​ | Select-Object *

Below are typical properties that you can get using queries like the above when you specify | Select-Object * :

  • ObjectId
  • DisplayName
  • City
  • Country
  • Fax
  • FirstName
  • LastName
  • ImmutableId
  • IsLicensed
  • LastDirSyncTime
  • LastPasswordChangeTimestamp
  • LicenseReconciliationNeeded
  • LiveId
  • MobilePhone
  • PasswordNeverExpires
  • PhoneNumber
  • PostalCode
  • SignInName
  • SoftDeletionTimestamp
  • State
  • StreetAddress
  • StrongPasswordRequired
  • Title
  • UsageLocation
  • UserPrincipalName
  • UserType
  • WhenCreated
  • *MemberOf (detailed explanation is given below)

If you don't specify | Select-Object * in your query, you will be able to get basic properties like:

  • UserPrincipalName
  • DisplayName
  • isLicensed

Sometimes it is useful to get the list of groups which the current user is a member of. This is possible to do with user synchronization requests. To do this you should add the 'MemberOf' attribute to the 'Lookup Attribute Names' parameter of your synchronization configuration in OpenIAM. MemberOf is not returned by default using Get-MSOLUser command. Also, it relies on an additional module - Azure AD. So, adding the 'MemberOf' attribute to 'Lookup Attribute Names' will result in +1 request for each user that is found. If you have a lot of users in your Azure AD it may have notable impact on sync speed, so please make sure that you request 'MemberOf' only in case when you really need this.

Groups synchronization

For running Azure groups synchronization you can use variations of the Get-MSOLGroup query. Some usage examples are below.

This query gets all groups with all properties that are availavble.

Get-MSOLGroup -All | Select-Object *

The query below selects all data about one particular group by group name:

Get-MSOGroup -SearchString 'Your_Group_Name' | Select-Object *

The query below selects one random group (usually useful for tests):

Get-MSOGroup -MaxResults 1 | Select-Object *

Below are typical properties that you can get using queries like the above when you specify | Select-Object *:

  • DisplayName
  • CommonName
  • Description
  • EmailAddress
  • GroupType
  • IsSystem
  • LastDirSyncTime
  • ManagedBy
  • ObjectId
  • *Membership (detailed explanation is given below)

If you don't specify | Select-Object * in your query, you will be able to get basic properties like:

  • ObjectId
  • DisplayName
  • GroupType
  • Description

Sometimes it is useful to get the list of members of synced group(s). This is possible to do with group synchronization requests. To do this you should add the 'Membership' attribute to the 'Lookup Attribute Names' parameter of your synchronization configuration in OpenIAM. Membership is not returned by default using the Get-MSOLGroup command. So, if you include this attribute it would result in +1 requests for each group returned. If you have a lot of groups in your Azure AD it may have notable impact on sync speed, so please make sure that you request 'Membership' only in case when you really need this.

Service principals synchronization

For running Azure service principals synchronization you can use variations of the Get-AzureADServicePrincipal query. Some usage examples are below.

This query gets all service principals with all properties that are availavble.

Get-AzureADServicePrincipal -All:$true | Select-Object *

The query below selects all data about one particular service principal selecting by ObjectId:

Get-AzureADServicePrincipal -ObjectId 'ba8078c7-e75d-40df-b10b-53c01cf18846' | Select-Object *

The query below selects all data about one random first service principal:

Get-AzureADServicePrincipal -All:$true | Select-Object * -First 1

Below are typical properties that you can get using queries like the above when you specify | Select-Object * :

  • ObjectId
  • ObjectType
  • DisplayName
  • AccountEnabled
  • ServicePrincipalType
  • AppDisplayName
  • AppId
  • AppOwnerTenantId
  • AppRoleAssignmentRequired
  • Homepage
  • PublisherName

If you don't specify | Select-Object * in your query, you will be able to get basic properties like:

  • ObjectID
  • AppID
  • DisplayName

Azure permissions synchronization

For running Azure permissions synchronization you can use the Get-oiAzurePermissionAssignments request. It supports a single parameter: SubscriptionIDs where you can set the list of subsctiptions separated by a comma. Examples are given below.

This query gets all permissions within two given subscriptions.

Get-oiAzurePermissionAssignments -SubscriptionIDs '11111111-fb94-4db4-93f3-ae4defd93cb9', '22222222-fb94-4db4-93f3-ae4defd93cb9'

The query below gets a single subscription record from specified subscriptions. This could be used for testing.

Get-oiAzurePermissionAssignments -SubscriptionIDs '11111111-fb94-4db4-93f3-ae4defd93cb9' | Select-Object -First 1

Get-oiAzurePermissionAssignments can grab the following properties for each permission assignment:

  • RoleAssignmentId
  • Scope
  • DisplayName
  • SignInName
  • RoleDefinitionName
  • RoleDefinitionId
  • ObjectId
  • ObjectType
  • CanDelegate
  • Description
  • ConditionVersion
  • Condition

Azure resources report usage

The Azure connector can generate reports about Azure resource usage inside the given Resource group, Subscription or tenant. To be able to generate such reports the service account should possess, at least, the 'Reader' role on a given level.

Assuming that the Azure services catalog is huge, and connector is just a default template, it supports reporting the limited set of resources out of the box. However, it is possible to extend it without issues by customizing the default connector.

Out-of-the-box connectors can generate reports about usage of following resources:

  • Microsoft.Compute/disks
  • Microsoft.Network/networkInterfaces
  • Microsoft.Network/networkSecurityGroups
  • Microsoft.Network/networkWatchers
  • Microsoft.Network/publicIPAddresses
  • Microsoft.RecoveryServices/vaults
  • Microsoft.Storage/storageAccounts
  • Microsoft.Sql/servers/databases Microsoft.Sql/servers*
  • Microsoft.Network/virtualNetworks
  • Microsoft.Compute/virtualMachines
  • Microsoft.Web/sites
  • Microsoft.Logic/workflows

To pull the Azure resource usage report you can use synchronization queries in a PowerShell style that look like using 'Get-oiAzureAccessReport' cmdlet. It supports the following parameters:

  • PrincipalProperty - specifies principal property of assignees' objects that will be returned. Allowed values: 'SignInName' and 'ObjectID'. Cannot be used with -SignInNames or -ObjectIDs as those parameters belong to different parameter set. Is used when you query all assignees, without limiting your search for given set of sign in names or object ids.
  • ObjectIDs - limits the search scope to given ObjectIDs. It is possible to specify several values as multiple strings separated by comma. Cannot be used together with the PrincipalProperty argument
  • SignInNames - limits the search scope to given SignInNames, exactly how the parameter above does.
  • Scope - either 'Tenant' or 'Subscription'. Specifies the level of extraction. If you have Reader access on lower level, for example single Resource group of one of subscriptions - you need to specify Subscription level and your search will be limited only to objects that you are allowed to access within your subscription.
  • ScopeID - identifier of your Subscription or Tenant depending on what you use in the parameter above
  • AllowedAttributes - optional parameter that allows you to limit your report to given resource types. Should be one of the supported resources on the list that were mentioned above.

Below are some practical examples of queries:

Get-oiAzureAccessReport -PrincipalProperty 'SignInName' -Scope 'Tenant' -ScopeID '90b27a81-12e5-499d-b7b8-b23274b10331'

The query above gets reports for all resources available at Tenant 90b27a81-12e5-499d-b7b8-b23274b10331 selecting SignInName as primary property.

Get-oiAzureAccessReport -SignInNames 'user1@openiam.com','user2@openiam.com' -Scope 'Tenant' -ScopeID '90b27a81-12e5-499d-b7b8-b23274b10331'

The query abovegets reports for all resources available for user1@openiam.com and user2@openiam.com at Tenant 90b27a81-12e5-499d-b7b8-b23274b10331.

Get-oiAzureAccessReport -ObjectIDs 'c4b14ca1-82ae-4ba1-81d9-375da19bad51', '2094b9f1-878c-4c38-9972-a2b2a9f62d31' -Scope 'Tenant' -ScopeID '90b27a81-12e5-499d-b7b8-b23274b10331'

The query above gets reports for all resources available for objects with Id c4b14ca1-82ae-4ba1-81d9-375da19bad51 and 2094b9f1-878c-4c38-9972-a2b2a9f62d31 at Tenant 90b27a81-12e5-499d-b7b8-b23274b10331.

Get-oiAzureAccessReport -PrincipalProperty 'SignInName' -Scope 'Subscription' -ScopeID '90b27a81-12e5-499d-b7b8-b23274b10331'

Gets all resource usage reports for all users inside available resources of Subscription 90b27a81-12e5-499d-b7b8-b23274b10331. The primary property will be SignInName.

Get-oiAzureAccessReport -PrincipalProperty 'SignInName' -Scope 'Subscription' -ScopeID '90b27a81-12e5-499d-b7b8-b23274b1033b' -AllowedAttributes 'Microsoft.Network/networkSecurityGroups','Microsoft.Compute/virtualMachines'

The same as the query above, but report scope is limiteed to virtual machines and network security groups only.

The result of this request will be the set of identities identified by ObjectID or SignInName. Each of those identities will have the set of resources by each type (described above). Each resource will have a JSON payload that describes what permissions does this identity have. For example, identity A has some permissions to 3 virtual machines. So 'Microsoft.Compute/disks' attribute will contain 3 permissions sets for each of those VMs and each would contain following properties:

  • ResourceName - Name of resource to which this permission was granted. In our case it will be the name of current VM
  • ResourceGroupName - Name of Azure resource group that contains current VM
  • ResourceId - ID of current VM
  • ResourceType - type of resource. In our case - 'Microsoft.Compute/disks'
  • SubscriptionId - ID of subscription that contains current VM
  • RoleDefinitionId - ID of role definition below
  • RoleDefinitionName - Name of role (like 'Reader', 'Owner' etc.)
  • AssigneeType - Type of identity that has this permission. For example, User or ServicePrincipal
  • AssigneeDisplayName - Display name of identity that was given permission for current object
  • AssigneeSignInName - If this assignee has a sign in name (like user) - it will contain it. Otherwise it will be empty (like for service principals)
  • AssigneeObjectId - ObjectID of identity that has this permission.
  • AssigneeCanDelegate - True or False, indicates if assignee can delegate permission to some other identities
  • RoleAssignmentId - Identifier of current role assignment

Azure AD Roles synchronization

The Azure connector can synchronize Azure AD roles and role memberships. In the Azure portal UI those roles could be found at 'Azure Active Directory' -> 'Roles and administrators'.

To run synchronization, you can use the query below:

Get-MsolRole

This request returns all available roles in your Azure AD. This request does not take parameters. However, if your 'attribute name lookup' contains 'membership' the result will include not only the full list of roles, but role members as well.

Attributes that are returned by the connector:

  • Name - the name of the role
  • ObjectId - Id of the role
  • Description - role description
  • IsEnabled - indicates if this role is enabled
  • IsSystem - indicates if this role is system generated or was created as a custom role
  • Membership - if 'attribute name lookup' contains 'membership' it will contain all members of the current role

Important to know - in Azure UI there is a role 'Global Administrator', which contains users that have unlimited control. When you run synchronization, this role is returned as 'Company Administrator'. This is actually the same role, but there is a difference between how the Azure portal UI displays it and PowerShell API returns it. So, this naming difference should be kept in mind.

Connector Troubleshooting and Tips

Connector troubleshooting is covered in the document that describes all .NET/PowerShell connector usage: PowerShell connector usage. Troubleshooting steps are the same for all connectors of this type. The following information is specific for this connector.

  • The Azure connector sets ‘ForceChangePassword’ as false by default. This is done because OpenIAM should be keeping the password on its side and control it. Also, the connector sets the ‘PasswordNeverExpires’ flag to prevent user's need to change the password so only OpenIAM controls password changes.
  • If you encounter issues connecting to your cloud, syncing data etc. the issue may be linked to being unable to connect to Microsoft cloud successfully. It is possible to run a tiny script, that connects using the MSOL module and validates the connection:
# Add the MSOnline module to the PowerShell session
Import-Module MSOnline
# Get credentials of the service account
$Credentials = Get-Credential
# Connect to Azure AD
Connect-MsolService -Credential $Credentials
# Optionally you may want to select just a single user to make sure that your service account can read
Get-MSOLUser -MaxResults 1

The connector mostly relies on the MSOnline module, however, for some operations it relies on the AzureAD module, so probably you would like to check how it connects using this module as well:

# Add the AzureAD module to the PowerShell session
Import-Module AzureAD
# Get credentials of Azure admin
$Credentials = Get-Credential
# Connect to Azure AD
Connect-AzureAD -Credential $Credentials

O365 group membership

  • When you create a new user and would like to assign O365 group to this user you should keep in mind that you will be able to assign group membership only after the user would get licensed and the license would be properly provisioned. According to Microsoft it may take up to 24 hours, but it usually takes around 20 minutes. At the same time if you work with Security groups, they could be assigned right away.
  • If your service account is not a member of the 'MailRecipients' role, the connector may be unable to properly handle O365 group assignment. So, if you work with O365 groups you shoud keep in mind service account permissions requirements.