Scenario:
You’ve created an application in Azure AD, and want to script allocating access to the app rather than using the web interface. App show up at https://myapps.microsoft.com
Azure AD Premium is required for group access which would be ideal, but if you don’t have that you’ll need to add access on a user by user basis.
Answer:
PowerShell of course. First, you’ll need Azure AD for PowerShell (Preview version 2.0.0.17 at time of writing).
The below script which I modified from Philippe’s comment here should cover both internal, cloud and B2B invited users. The original script was using -objectid rather than -searchstring which works better and is more accurate for the internal and cloud accounts, but doesn’t work at all for B2B accounts.
The AppID can be obtained from this command:
Get-AzureADApplication -SearchString “Display Name for App”
Put the corresponding AppID into the below script, and you’re good to go. You’ll get prompted for Azure AD credentials as per usual. You can also get this
This is designed for a single user addition, but you could easily import the email addresses from a CSV file, and do a ‘for each’ on each entry like I did here.
# The UserPrincipalName or ObjectId of the user $userId = "[email protected]" # The AppId (a.k.a. "client ID") of the app to assign the user to $appId = "AppIDGoesHere" # Connect to Azure AD Connect-AzureAD -Confirm # Get the user to be added $user = Get-AzureADUser -searchstring $userId # Get the service principal for the app you would like to assign the user to $servicePrincipal = Get-AzureADServicePrincipal -Filter "appId eq '$appId'" # Create the app role assignment new-AzureADUserAppRoleAssignment -ObjectId $user.ObjectId -PrincipalId $user.ObjectId -ResourceId $servicePrincipal.ObjectId -Id ([Guid]::Empty)
Note: If you try this and get the error below, it’s because the app is already assigned.
new-AzureADUserAppRoleAssignment : Error occurred while executing NewUserAppRoleAssignment
StatusCode: BadRequest
ErrorCode: Request_BadRequest
Message: One or more properties are invalid.
At Z:\script.ps1:17 char:1
+ new-AzureADUserAppRoleAssignment -ObjectId $user.ObjectId `
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [New-AzureADUserAppRoleAssignment], ApiException
+ FullyQualifiedErrorId : Microsoft.Open.AzureAD16.Client.ApiException,Microsoft.Open.AzureAD16.PowerShell.NewUser
AppRoleAssignment
Hey! This is a long shot, but someone might answer:
I’m trying to use your script, but I’m getting the error you mention at the end, even though the user’s role is “Unassigned” in AzureAD Portal. I’ve tried with a few different users, whether they were assigned or not, and I get the same thing.
Has anything changed from October ’16 to now that might render this script non-working ?
Also, just as an FYI: In $userId, you cannot use the UPN/email address of the user, as it returns nothing when you get Get-AzureADUser, and then, later one, you get an error “Cannot bind argument to parameter ‘ObjectId’ because it is null @ line:17 char: 44
Thanks in advance!
Hi Alex, I’m on holidays right now but can check in about a week if you like? If you work it out before then let me know :)
Hi Adam,
Sure, no problem. It’s your holidays, enjoy them, don’t worry about us noobs! hehe
I still haven’t figured out why it’s not working, but haven’t had much time to do so anyway :P
I’m back now :) I used this early in the year and it worked fine.
The $userid works fine for me – what do you have to use in place of the UPN to get it to work for you? I’m wondering if that’s why the second part isn’t doing what you want…
I got my first error to go away but now I’m with Alex P.
The Get-AzureADUser -SearchString parameter returns null when using UPN but worked when I used the MailNickName attribute (which is just the alias – for us, first initial last name).
Using the alias fixed the null problem but I am getting the same error Alex P. is getting. The one stated above, even though the user is unassigned to the application.
P.S. apologies on the way late responses, I’m over here in the US on EST.
Thanks,
Michael S.
Michael, I got an email saying you had posted a comment which apparently solved your issue, but I can’t seem to find the comment here. Was it deleted ? That’s what I got as a resume from the email, but I can’t find that anywhere on the page: https://www.dropbox.com/s/31knqiy33gkdg7y/Screenshot%202017-02-08%2014.27.05.png?dl=0
Thanks,
Alex P, the comment you can’t see is still awaiting Adam’s approval. Probably because it includes my final script which is long.
Here’s a folder with the script in it: https://www.dropbox.com/sh/geigb8co8rnjuwi/AAAuT2_4AQ_y3XwPMmb5yrRJa?dl=0
Happy coding!
Apologies, approved!
YES! This works perfectly. I had to do one small tweaking because my instance of Powershell wasn’t having it with your quotation marks for some reason, but after adjusting this, it works perfectly.
Thank you very much for your help, this’ll save a LOT of time :)
Great job on putting this together! Hope your holiday was fun!
Question, I am getting an error with the -Id parameter of the last line of code.
StatusCode: BadRequest
ErrorCode: Request_BadRequest
Message: Cannot convert a primitive value to the expected type ‘Edm.Guid’.
I am unsure of what the -Id parameter is even looking for? Any ideas?
Hi Michael,
Had a great break thanks :)
I was a bit lost on that part of the command too – I found it here:
https://social.msdn.microsoft.com/Forums/azure/en-US/de3c56e2-9010-463c-9bbd-faf70069cd26/azure-ad-manage-users-with-powershell?forum=WindowsAzureAD
Philippe says there “To retrieve the possible AppRole values to be used with the -Id parameter, one would look at the AppRoles property of the ServicePrincipal object.”
For my testing and then use in prod, it worked fine leaving it as the null value. In theory you should be able to just type $ServicePrincipal and see what the AppRoles property contains.
Hope you report back after seeing what you find there :)
Thanks
Adam
Glad your break was excellent :D
The msdn article cleared some things up. I was able to find the AppRoles.Id, however, I’m still receiving the same error. In your test & prod environments, are you running Azure AD Premium?
We are not and therefore role-based assignment isn’t available. I think this might be the cause of the error.
Thoughts?
Michael
OK! I got it! I had to make 2 updates to your original script:
1. (Line 11) Instead of using -searchstring I used -objected
– This solved Alex P’s issue of null $user
2. (Line 17) Instead of user the empty guid I used the $ServicePrincipal.appRole.Id
– This solved my problem with the badRequest error pertaining to one or more properties being invalid.
P.S. I uninstalled the AzureADPreview module and installed the AzureAd module.
AzureADPreview: https://www.powershellgallery.com/packages/AzureADPreview/2.0.0.52
AzureAD: https://www.powershellgallery.com/packages/AzureAD/2.0.0.33
This was solved largely in part by the article you sent and my fiddling around. Great job team! :D
——————————————————————-SCRIPT————————————————————————–
# The UserPrincipalName or ObjectId of the user
$userId = “[email protected]”
# The AppId (a.k.a. “client ID”) of the app to assign the user to
$appId = “AppIDGoesHere”
# Connect to Azure AD
Connect-AzureAD -Confirm
# Get the user to be added
$user = Get-AzureADUser -ObjectId $userId
# Get the service principal for the app you would like to assign the user to
$servicePrincipal = Get-AzureADServicePrincipal -Filter “appId eq ‘$appId'”
# Create the app role assignment
New-AzureADUserAppRoleAssignment -ObjectId $user.ObjectId -PrincipalId $user.ObjectId -ResourceId $servicePrincipal.ObjectId -Id $servicePrincipal.AppRoles.Id
EDIT: #2 should say “Instead of USING” not user.
Sorry for the delay in responding, great work! Azure AD has come out of preview as you suggested. I really should put this onto GitHub.
Hi Adam,
I also had to change searchstring to objectid
I am getting this error from line 14:
Get-AzureADServicePrincipal : Error occurred while executing GetServicePrincipals
Code: Request_BadRequest
Message: Syntax error at position 7 in ‘appId -eq idnumber’.
HttpStatusCode: BadRequest
HttpStatusDescription: Bad Request
HttpResponseStatus: Completed
so I changed it to $servicePrincipal = Get-AzureADServicePrincipal | Where-Object {$_.appid -eq $appId}
Hi Geoff,
I’ve restested and it still works for me, but my post had changed the quotes to slightly different characters. Your method works too. Any chance you can try typing this out manually and see if it works?
$appid = “put in an app ID here”
Get-AzureADServicePrincipal -Filter “appId eq ‘$appId'”
Hi Adam,
attempting your script i get this error. checked to see if user already had permissions and they dont. Please advise.
new-AzureADUserAppRoleAssignment : Error occurred while executing NewUserAppRoleAssignment
Code: Request_BadRequest
Message: One or more properties are invalid.
RequestId: cbe31cff-1a91-4ee9-9fc9-68b4dedda9ab
DateTimeStamp: Mon, 11 Mar 2019 19:26:22 GMT
HttpStatusCode: BadRequest
HttpStatusDescription: Bad Request
HttpResponseStatus: Completed
At line:15 char:2
+ new-AzureADUserAppRoleAssignment -ObjectId $user.ObjectId -Principal …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [New-AzureADUserAppRoleAssignment], ApiException
+ FullyQualifiedErrorId : Microsoft.Open.AzureAD16.Client.ApiException,Microsoft.Open.AzureAD16.PowerShell.NewUserAppRoleAssignment
Hi Evan,
I think that’s exactly the same error I posted at the bottom of my blog post, if the app is already assigned you’ll see that.
Should be able to run ‘Get-AzureADUserAppRoleAssignment’ find the one you don’t want and remove it if necessary, then run the script again, but you probably don’t need to do any of that if it’s already assigned.
That’s the problem I am having, I am getting alerted that the user is already a member but is not a member.
I run the above command against my account and it is correct. I run it against someone who is not apart of that happen and it errors out. I even try doing everything strictly on either object id of the user and application and that even doesnt work.
Something with this is not right,
I’ve just tested this again and it still works for me. Here’s the official doco of the command: https://docs.microsoft.com/en-us/powershell/module/azuread/new-azureaduserapproleassignment?view=azureadps-2.0
The second example command there talks about giving the user a specific app role, is it an app that needs a role defined?
I know it’s been a while since there was activity on this thread, I am hoping for a little guidance. I was successful getting this to work for one user, but seem to be failing at getting this to work for multiple users. I have a list of 100 plus users, but I am only testing with two currently. The csv file has a header of UserPrincipalName and underneath that are the users listed, firstname lastname. Here is what I have for my script…
$users = Import-Csv -Path “C:\users.csv”
ForEach ($user in $users){
# The AppId (a.k.a. “client ID”) of the app to assign the user to
$appId = “client ID”
# Get the user to be added
$user = Get-AzureADUser -searchstring $userId
# Get the service principal for the app you would like to assign the user to
$servicePrincipal = Get-AzureADServicePrincipal | Where-Object {$_.appid -eq $appId}
# Create the app role assignment
new-AzureADUserAppRoleAssignment -ObjectId $user.ObjectId -PrincipalId $user.ObjectId -ResourceId $servicePrincipal.ObjectId -Id ([Guid]::Empty)
}
So it does add one user, but not the second. Any help would be appreciated.
I’m going to guess it’s this line – the $userid variable hasn’t been set:
$user = Get-AzureADUser -searchstring $userId
without knowing that’s in your users.csv for the headings of each column, something like:
$username = Get-AzureADUser -searchstring $user.username
I suspect you set $userid once which is why $user keeps getting set to whatever that value is, so you’re importing the giant user list but then not actually using the current user variable for it.
Hello Adam. So I changed the format of script a little and decided to use the first and last name as well as a second column with the ObjectID.
DisplayName ObjectID
First Last xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx
That seemed to get it working.
# Connect to Azure AD
Connect-AzureAD -Confirm
# The AppId (a.k.a. “client ID”) of the app to assign the user to
$appId = “Application ID”
# Get the user to be added
#$user = Get-AzureADUser -searchstring $userId
# Get the service principal for the app you would like to assign the user to
$servicePrincipal = Get-AzureADServicePrincipal | Where-Object {$_.appid -eq $appId}
$users = Import-Csv -Path “C:\users.csv”
# Create a ForEach loop to iterate over the users in the CSV file
ForEach ($user in $users) {
# Create the app role assignment
new-AzureADUserAppRoleAssignment -ObjectId $user.ObjectId -PrincipalId $user.ObjectId -ResourceId $servicePrincipal.ObjectId -Id ([Guid]::Empty)
}