Fortunately, I have recently discovered a great way to create Azure AD App Registrations using the Azure CLI 2.0. This also includes adding any permissions the app requires on resources e.g. Microsoft Graph, Office 365 SharePoint Online etc. This has not been previously possible with the Azure AD PowerShell Cmdlets.
So in this post, let's go through what is needed to achieve this:
Once you have the CLI, here is the code to create an Azure AD App Registration including the required permissions:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The JSON in the requiredResourceManifest.json file can be fetched from the manifest of an App registration already created in Azure AD. So the recommendation would be to manually create an App Registration in Azure AD and configure the required permissions. Once you have the right set of permissions, edit the manifest and grab the JSON from the requiredResourceAccess array.
az ad app permission admin-consent --id [--subscription]
If you still want to use the portal to grant the permissions you can do so as an Admin by going to the app and clicking on the "Grant Permissions" button:
Recently, a client had asked us to synchronise user properties from their Azure AD profile to custom properties in their SharePoint UserProfile. This had to be a scheduled process as the data had to be kept up to date as well as it had to cater for any new profiles created in Azure AD/SharePoint.
We decided to use Azure Functions for this given the ease of configuring a timer triggered function (to run on schedule) and also the fact that functions run on a consumption based billing plan. This means that the client would get charged only for when the function executes (oh and also, the first million executions are free every month)
The main challenge we had to overcome was the limitation that an Azure Function has a default timeout of 5 minutes (which can be increased up to 10 minutes at the time of this writing) This means that if we were using a single Azure Function to update SharePoint UserProfile Properties for thousands of users, we were going to hit the timeout sooner or later.
Fortunately, Durable Functions went GA recently which means that we have a way of managing state in the traditionally "state-less" Azure Functions. With durable functions, we can create an "activity" function to update the SharePoint User Profile properties for a single user. This function can be called in a loop for each user from an "orchestrator" function. Each run of the activity function is treated as a single execution and can be finished in the 5 minute default timeout.
The Durable Function workflow can be categorised into three different types of functions:
1) Client Function
These are standard Azure Functions which can be triggered by external events like timers, HTTP requests, queues etc. The only difference being they have an OrchestrationClient binding which is required to start orchestrations.
In our case, the Client Function is a simple timer triggered function which uses the OrchestrationClient to start a new Orchestration Function with the name O_SyncProfileProperties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
As the name suggests, the Orchestrator function acts as a coordinator of the Durable Functions workflow. It does the job of starting, stopping and waiting for activity functions and is also in charge of passing data (or state) in between them.
In our case, it calls the A_GetUsersToSync activity function to get the user profiles from Azure AD (using the Microsoft Graph API which is out of scope for this article) and then loops through the users to call the A_UpdateSharePointProfile function for each user
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
As you might have guessed by now the Activity function is the one which actually does all the heavy lifting. For example, the actual CSOM code which will update the SharePoint UserProfile properties will live in the A_UpdateSharePointProfile activity function:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters