How to add/update user permissions on environment's security through REST API on Azure DevOps?

1.2k Views Asked by At

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":{}}
2

There are 2 best solutions below

2
Bruno On BEST ANSWER

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.

0
Justin On

@Bruno answer can have its header greatly simplified, also the body can be constructed using ConvertTo-Json to avoid syntax errors.

function Get-AzureDevOpsAuthenticationHeader
{
    param (
        [Parameter(Mandatory=$false)][SecureString]$PAT
    )
    $AzureDevOpsPAT = (new-object System.Net.NetworkCredential -argumentList " ", (Get-AzureDevOpsPAT -PAT $PAT)).Password
    $AzureDevOpsAuthenicationHeader = @{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($AzureDevOpsPAT)")) }
    return $AzureDevOpsAuthenicationHeader
}


#parms
$orgname='...'
$userid='guid'
$projectid='guid'
$environmentid='int'
$PAT = '...' | ConvertTo-SecureString -asplaintext -force

#get the header
$header = Get-AzureDevOpsAuthenticationHeader -PAT $PAT                                                                                                                                                  

#construct the body
$body = ConvertTo-Json -InputObject @(,@{userId= $userid;"roleName"="Administrator"}) 

#send the request
$uri = "https://dev.azure.com/$orgname/_apis/securityroles/scopes/distributedtask.environmentreferencerole/roleassignments/resources/$projectid`_$EnvironmentID`?api-version=5.0-preview.1"

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

output:

count value                                                             
----- -----                                                             
    1 {@{identity=; role=; access=assigned; accessDisplayName=Assigned}}