Introduction
Let's set the context of our scenario: you're about to go live, the environment is secured with an AAD Security Group, and you need to ensure all the users have their security roles assigned before D-day.
Otherwise, users will face an "Access Denied" error screen:
You'll find out that when the user refreshes the page, everything will sync between AAD and Dataverse, and the issue will disappear. However, that's not an option for you when deploying a massive application as it will be perceived as an error and your team will be overflown with tickets / support requests.
To solve this, I recommend using the Power Platform Administration PowerShell module. The commands that you'll need are:
#Connect to your environment using a Service Principal
Add-PowerAppsAccount -Endpoint "prod" -TenantID $tenantId -ClientSecret $clientSecret -ApplicationId $applicationId
#Sync user between AAD and systemuser table
Add-AdminPowerAppsSyncUser -EnvironmentName $environmentId -PrincipalObjectId $aadObjectId
In the rest of the article, I will walk through the different steps and my reasoning behind it. I will be delighted to know your thoughts on this or if you have a better way to do it that you can share with the community 😁💪
Let's elaborate!
So, you have a Power Platform Environment (with Dataverse). Its access is controlled by an Azure AD Security Group:
Roughly, the steps to grant a user access to an application are:
Add the new user into the AAD Security Group "Awesome App Security Group".
Assign the user a security role.
Share the application with the user (hopefully, this will also be controlled with an AAD Security Group).
On paper, everything's set: users will log in to the application using the link provided as part of your communication and adoption plan.
Now, it's one week before the Go Live and you are about to assign the security roles to all the users following the Excel provided by the business application owners. You log in to the Power Platform environment and realize that these people are not in the environment.
Okay, not to panic. Your colleague must have forgotten to add these people into the Azure Active Directory Security Group that functions as "first filter" for your environment. Now you do start to worry as you realize that the AAD group is fine.
So, let's understand what's happening behind the scenes:
Solution
You still have almost 1w before the Go Live, so you start thinking on solutions. But first, what's the real problem here? Well, in order to assign a security role to a user, she needs to be in the systemuser table beforehand. So, how do we manage to "force" the syncing between Azure Active Directory and our Power Platform Environment?
Well, allow me to introduce you to the (PowerShell) Power Apps Admin module:
If you're completely new to PowerShell and/or you don't want to use this piece of technology, you still can use Power Automate to achieve the same. If that's the case, check this article I found on the Community Blog: PowerApps force sync users from Azure AD to Data V... - Power Platform Community (microsoft.com)
Now, this is how I usually approach this scenario:
1. Get the list of users from the business stakeholders
In general, you need to partner with the business owners of your solution to succeed. In this case, you'll need their help to get the users who need to be onboarded in the application.
I would typically ask for an Excel with their UPNs / email addresses as they probably already have that or is going to be feasible for them to get.
2. Find their AAD object ids
The PowerShell command we're going to use requires the user's Azure Active Directory object id. This is a unique GUID for each user in the tenant. As I'm used to the PnP.PowerShell library, I usually do the following:
#Connect to a SharePoint Site you have access to using the interactive prompt:
Connect-PnPOnline -Url "<SPO site>" -Interactive
#Go through all the Excel to find and store the users' object ids.
#You can read the Excel use the Import-Excel module or save as CSV and use the default PowerShell features
$users = Get-Content -Path "<path to the CSV file>" | ConvertFrom-CSV -Delimiter ";"
$outputUsers = [System.Collections.ArrayList]::new()
foreach ($user in $users) {
$aadUser = Get-PnPAzureAADUser -Identity $user."Email"
$outputUsers.Add( [PSCustomObject]@{
"Name" = $user."Name";
"Email" = $user."Email";
"Country" = $user."Country";
"Role" = $user."Role";
"AADObjectId" = $aadUser.Id
})
}
#Export your data to a new CSV file with the AAD Object Ids
$outputUsers | ConvertTo-Csv -Delimiter ";" > "<path and for your output file>.csv"
Now, this is what you should get after those few lines of PS:
3. Sync AAD with Dataverse's systemuser table
We're ready to force the sync and for that, this is going to be our key command:
Add-AdminPowerAppsSyncUser -EnvironmentName $environmentId -PrincipalObjectId $aadObjectId
Putting everything together, we could have another script that would read our recently created CSV file and perform all the syncing operations like this:
#Connect to your environment using a Service Principal
Add-PowerAppsAccount -Endpoint "prod" -TenantID $tenantId -ClientSecret $clientSecret -ApplicationId $applicationId
$usersToSync = Get-Content -Path "<path to the CSV file>" | ConvertFrom-CSV -Delimiter ";"
foreach ($user in $usersToSync ) {
Add-AdminPowerAppsSyncUser -EnvironmentName $environmentId PrincipalObjectId $user."AADObjectId"
}
Wrapping up
We've seen how AAD - Dataverse syncing works and a way to force it so that every user's security configuration is set before they log in for the first time.
I prefer the PowerShell approach as I use this technology to automate a lot of the operations that come with developing solutions, deploying them, ALM and administering Power Platform environments.
I hope this article was useful to you! Let me know in the comments if you are interested in more of this stuff!
See you around,
Andres
Comments