Working with PowerShell always brings up a few interesting gotchas, as things are not always what they seem at the surface. I guess you could say that for any development tool out there, but somehow it happens every time I need to do something with PowerShell. Case in point, you would think that assigning an administrator role would be a simple call to one cmdlet…but things are never quite that simple :-/
If you look at the Azure AD Roles and administrators page in the Azure portal, you see a long list of administrator roles you can assign to users (or service principals). Compare that to the list returned by the Get-AzureADDirectoryRole cmdlet however and you only see a small subset.
What’s happening here?
The part that’s not necessarily clear from the documentation is that the Azure portal shows a list of available roles (or templates). It seems obvious enough that this would be the case in the portal, as you may not have assigned all of these roles to users yet and you would expect a complete list. But as you can see from the PowerShell results, the fun starts when you think you could just get the role and assign it to a user. How can you assign a role if you can’t get to its object id? How do you get a list of all of the available roles in PowerShell?
After digging for some time you (me) stumble across this gem, the Get-AzureADDirectoryRoleTemplate cmdlet which returns all of the available roles (or templates). Eureka!! Let’s use this object id and assign it to a user with the following snippet…
#Get the user
$UserObject = (Get-AzureADUser | where {($_.UserPrincipalName -eq 'test@28twelve.consulting')})
$UserObject
#Get the role
$AdminRoleObject = Get-AzureADDirectoryRoleTemplate | where {$_.DisplayName -eq 'Application Administrator'}
$AdminRoleObject
#Assign the role to the user
Add-AzureADDirectoryRoleMember -ObjectId $AdminRoleObject.ObjectId -RefObjectId $UserObject.ObjectId
Not so fast…you get an error saying that the role doesn’t exist…and we know this from what we’ve seen earlier, but it still isn’t clear how we would be able to get an object id to assign.
The solution
The solution is buried underneath many levels of documentation and hours of searching/experimenting:
- Attempt to get the administrator role, using the Get-AzureADDirectoryRole cmdlet.
- If the first step doesn’t return anything, it means that the role has probably never been assigned to a user and we have to enable it in our tenant first. Get the template for the role with the Get-AzureADDirectoryRoleTemplate cmdlet.
- Once you have the template, enable it with the Enable-AzureADDirectoryRole cmdlet. This will create an instance of the role within your tenant, with its own unique object id.
- Now you’ll be able to get to the role and its object id with the Get-AzureADDirectoryRole cmdlet.
- Assign the role to the user (or service principal).
I wish the PowerShell documentation was a bit more explicit in cases like these. Adding a simple comment or two to the documentation of the Get-AzureADDirectoryRole cmdlet will certainly help avoid the hours of confusion and searching…
Want to download the PowerShell script to assign administrative roles? Get it from my GitHub repo.
Hi Martin!
Nice article, but even though the role I am trying to assign is enabled, the script did not work, and I did receive the same error message… I think the issue is that you are using the cmdlet Get-AzureADDirectoryRoleTemplate, whereas you should be using Get-AzureADDirectoryRole!!! However, that did not do the trick for me…
What does Get-AzureADDirectoryRole return?
An instance of a DirectoryRole class, whereas Get-AzureADDirectoryRoleTemplate returns a DirectoryRoleTemplate I believe. Moreover, when I inspect both objects, I can clearly see that the ObjectId is accurate when using Get-AzureADDirectoryRole and can actually be mapped to the role I want to fetch. The same does not happen when I use Get-AzureADDirectoryRoleTemplate.