2

screenshot

I need to add user permission when creating an environment through REST API with PowerShell.

I've looked at the network trace and this is the header when I tried to manually add a user permissions

Request URL:

https://dev.azure.com/{org}/_apis/securityroles/scopes/distributedtask.environmentreferencerole/roleassignments/resources/{project_id}_{env_id}

Request Method: Put

Request Body:

[{userId: "{id_of_user}", roleName: "Administrator"}]

And this is the code I tried:

# other code
...
$body = @(
  @{ 'userId' = '{id_of_user}'; 'roleName': 'Administrator' }
) | ConvertTo-Json
Invoke-RestMethod -Uri $uri -Method Put -Body $body -ContentType "application/json" -Headers $header

But it is returning:

{"count":0,"value":{}}
Jess
  • 29
  • 7

1 Answers1

2

The only missing thing is that in your body, you should provide an array instead of a single object, here is a working example:

$uri = "https://dev.azure.com/bauca/_apis/securityroles/scopes/distributedtask.environmentreferencerole/roleassignments/resources/{project_id}_{env_id}"
$id_of_user = 'YOUR_USER_ID'
$tokenbase = 'YOUR_PAT'
$header = @{
 "authority"="dev.azure.com"
 "Authorization"= "Basic $tokenbase"
 "method"="PUT"
 "path"="/{ORG}/_apis/securityroles/scopes/distributedtask.environmentreferencerole/roleassignments/resources/{project_id}_{env_id}"
 "scheme"="https"
 "accept"="application/json;api-version=5.0-preview.1;excludeUrls=true;enumsAsNumbers=true;msDateFormat=true;noArrayWrap=true"
 "accept-encoding"="gzip, deflate, br"
 "accept-language"="en-US,en;q=0.9,pt;q=0.8,nl;q=0.7"
 "origin"="https://dev.azure.com"
 "x-vss-reauthenticationaction"="Suppress"
} ` 

$body = "[{`"userId`":`"${id_of_user}`",`"roleName`":`"Administrator`"}]"


Invoke-RestMethod -UseBasicParsing -Uri $uri -Method "PUT" -Body $body -ContentType "application/json" -Headers $header

The returned results should be something like:

@{displayName=USER_NAME; id=USERID; uniqueName=USER_UNIQUENAME} 

The API documentation is not clear about that, so, in this situations what I'd recommend you to do, is just use Chrome to do the requests through the UI, then inspect element and grab the network information of the request, after that 'Click with the right button' and then select 'Copy to Powershell' you'll see exactly what is the 'body' required to perform the request.

Bruno
  • 924
  • 9
  • 20
  • 1
    I just copied your $body code and it seems to work. I'm pretty sure I passed an array for the $body. Guess not. – Jess Jun 12 '22 at 07:22
  • 1
    PowerShell flattens single element arrays to the single element. To enforce an array use a comma: @(,$myitem) – Carl in 't Veld Jun 24 '23 at 06:06