As I mentioned in a recent post I’ve recently dived back into Microsoft Identity Manager. The focus of this post is some development I recently did to build a Microsoft Dynamics 365 Finance & Operations Management Agent for Microsoft Identity Manager. As this was custom development I used my favourite extensible management agent, the Granfeldt PowerShell Management Agent.
A caveat straight out of the gate was how to integrate with Dynamics 365 for Finance & Operations. Without any prior experience with Dynamics 365, I was unaware of the different products and their heritage. Microsoft Dynamics 365 for Finance & Operations is a rebrand of Dynamics AX. My initial misunderstanding was that I could use the Microsoft Graph Financials API to access the data I needed. No, the Microsoft Graph Financials API is for Dynamics 365 Business Central.
With my new learned knowledge that I couldn’t use Microsoft Graph to get what I needed, I set about working how to get access to Employee data from Dynamics 365 for Finance and Operations. The answer was using the Open Data Protocol (OData). For Authentication, Azure Active Directory is the prescribed method.
The final step was to workout the Dynamics 365 for Financials and Operations Entities that contained the data I needed for employees to bring into Microsoft Identity Manager. I started writing a few functions to query Dynamics 365 when I realized with the myriad of entities I needed, I figured/hoped that someone has surely been in this position before. A few searches on the PowerShell Gallery later and I found the d365fo.integrations module. Huge thanks to Mötz Jensen for that.
Update: 29 April 2021
Mötz advises that changes to the ODATA API Endpoints may see throttling (HTTP 429) responses. Make sure you have the latest d365fo.integrations module.
Now for what you’ve read this far for. How to build and configure a Granfeldt PowerShell Dynamics 365 Finance & Operations Management Agent for Microsoft Identity Manager.
Azure AD Registered Application
Using the Azure Portal you will need to register an Azure AD Application, and generate a Client Secret for it. Record the Tenant ID, Application ID (Client ID) and the Client Secret values. That is all we need from Azure AD as we will use it to authenticate, but the resource we will be accessing is the Dynamics 365 for Finance & Operations OData API.
Dynamics 365 for Finance and Operations API
From the Dynamics 365 for Finance and Operations System Administration => Setup => Azure Active Directory applications configuration provide the Client ID of the AAD Registered Application you created above. And provide a name for the integration and a Dynamics 365 Account with the necessary ODATA API Permissions for the entities you will be retrieving. In my implementation I needed access to the following Dynamics 365 Entities.
Record the base URL in the address bar of your browser from the Finance and Operations Configuration portal as this will be the environment we will connect to. e.g. https://<yourtenant>.sandbox.operations.dynamics.com
PowerShell integration with Dynamics 365 Finance and Operations
In this example I document reading data in from Dynamics 365 Finance and Operations. As mentioned in the prerequisites the Dynamics 365 Entities I needed access to were Workers, Positions, Employments and DepartmentsV2.
Using the d365fo.integrations module you can easily authenticate to Azure AD and get an access token for authorization to your Dynamics 365 Finance and Operations Tenant. Install the module from the PowerShell Gallery in an Administrative PowerShell session on your MIM Sync Server using the following command.
install-module d365fo.integrations -force -allowclobber
Import the d365fo.integrations module.
Get an Azure AD Access Token using the Get-D365ODataToken cmdlet.
$d365Token = Get-D365ODataToken -Tenant 'yourAADTenantID' -Url "https://yourD365Tenant.sandbox.operations.dynamics.com" -ClientId "yourAADClientID" -ClientSecret "yourAADClientSecret"
We can use the Get-D365ODataPublicEntity cmdlet to locate entities based on naming. e.g. to locate entities that contain ‘Employees‘ the following will return them.
Get-D365ODataPublicEntity -EntityNameContains Employees -Token $d365Token -Url "https://yourD365Tenant.sandbox.operations.dynamics.com"
The PSMA will then make extensive use of the Get-D365ODataEntityData cmdlet with the -TraverseNextLink switch to return all results from an Entity.
Dynamics 365 for Finance & Operations OData API Entity Relationships
As I worked through accessing the necessary data I required to pull into MIM from Dynamics 365, I was initially flying blind. I was thrown a few entity names and I needed to figure it out for myself. Once I had, I needed to educate others so I put together this relationship diagram. The bold references show the joins between entities. The green attribute highlights show where the values for the ‘person‘ objectClass on the PSMA will come from.
PowerShell Management Agent
- The Dynamics 365 Finance and Operations PSMA example;
- supports Full Imports only from Dynamics 365 Finance and Operations
- using the Granfeldt PowerShell Management Agent though we will still need to create a Export and Password script. Create the files with empty content.
- is not configured to page imports
- does not include logic for workers with multiple active positions / transfers
- utilises my JWTDetails PowerShell Module to check the expiry of the Azure AD Access Token. You can install that on your system using the details from the link above.
- logs events into the Windows Application Event Log. You will need to configure the ‘source‘ of your events for that to function. See the details in this post for how to configure your event source.
- supports Full Imports only from Dynamics 365 Finance and Operations
Here is the schema script for the Dynamics 365 Finance and Operations PSMA with a base set of employee attributes for this example.
Import Logic and Process Flow
To help understand the sample Import Script below, here is a process flow for it. Referencing this flow when analyzing the import script will help you to quickly understand it.
Here is the example Import Dynamics 365 Finance and Operations PSMA script. Update line 12 for your Dynamics 365 Finance and Operations Tenant URL, line 14 for your Azure AD Tenant ID. If you use the latest Granfeldt PSMA you could put these items in the new Configuration property of the PSMA. This MA was developed before that was released.
Management Agent Configuration
On a MIM Sync Server with the Granfeldt PSMA installed copy the Schema, Import and your blank Password and Export scripts to an appropriate directory. Create a new PowerShell Management Agent and on the Connectivity configuration page enter the Azure AD registered application Client ID for Username. Enter the Azure AD registered application Client Secret for the Password. In this example I’m not using Paged Imports. You can configure that if you require, updating the Import Script based on this example.
Configure each page of the Management Agent configuration as required for your environment and implementation. Create Run Profiles for Import and Sync as per your standards and run them. The Management Agent Partition.
The Management Agent Object Type from the Schema script.
Attributes to select based off the schema script.
The anchor as referenced in the schema script.
Any filters for the Management Agent.
Join and Projection rules if using classic rules.
Attribute flow, also only if using classic rules.
And disable Password Management as it hasn’t been implemented.
In this post I’ve provided a working example for importing Dynamics 365 Finance and Operation Workers into Microsoft Identity Manager. This example can then be extended for additional attributes, and logic required for each individual implementation.