Manage release permissions

Last week one of the customer reported that they are not able to manage the folder permissions of release definitions because they denied permissions to manage permissions and due to which the UI to manage security is not showing up even for project collection administrators. We fixed the UI bug in our latest code so that it always show up the security dialogue and Nishu Bansal wrote a powershell script which uses the security rest APIs to manage the security. I am pasting the script for you so that you can learn how to programmatically manage RM security.

$accountName = "<myaccount>"
$projectName = "myproject"
$personalAccessToken = "<my token>"
$user = "aseemb"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$personalAccessToken)))

function getProjectId() {
$projects=((Invoke-RestMethod -Method Get -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -ContentType "application/json" -Uri https://$accountName.visualstudio.com/_apis/projects?api-version=4.1).value | Select-Object id, name)
$projects | % {
if ($_.name -ieq $projectName) {
return $_.id
}
}
}

function getACEObject([string] $descriptor,[int] $allow, [int] $deny) {
$aceObject = New-Object PSObject
$aceObject | Add-Member -type  NoteProperty -name descriptor -Value $descriptor
$aceObject | Add-Member -type  NoteProperty -name allow -Value $allow
$aceObject | Add-Member -type  NoteProperty -name deny -Value $deny
return $aceObject
}

function Set-ACE([string] $folderPath) {
$projectId=getProjectId
$token=("{0}/{1}" -f $projectId, $folderPath)
$result=((Invoke-RestMethod -Method Get -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -ContentType "application/json" -Uri "https://$accountName.vsrm.visualstudio.com/_apis/AccessControlLists/c788c23e-1b46-4162-8f5e-d7585343b5de?token=$token&api-version=4.1&includeExtendedInfo=true").value)
$ace=($result | Select-Object acesDictionary).acesDictionary
Write-Output ("Existing ACLs")
foreach($info in $ace.PSObject.Properties) {
$aceObject = getACEObject -descriptor $info.Value.descriptor -allow $info.Value.allow -deny $info.Value.deny
Write-Output ($aceObject)
}
$aces = @()
foreach($info in $ace.PSObject.Properties) {
$descriptor=$info.Value.descriptor
#             if ($descriptor -match '-0-0-0-0-1') {
#$allowValue = $info.Value.allow -bor 512 # Enabling Allow bit for Release Administer permissions
$allowValue = $info.Value.allow
$denyValue = ($info.Value.deny -band (-bnot (1 -shl 9)))  #  Disabling Deny bit for Release Administer permissions
$aceObject = getACEObject -descriptor $descriptor -allow $allowValue -deny $denyValue
Write-Output ("Setting new ACE")
Write-Output ($aceObject)
$aces += $aceObject
#             }
}
if ($aces.count -gt 0 ) {
Write-Output ("Setting new ACLs")
Write-Output ($token)
$aclObject = New-Object PSObject
$aclObject | Add-Member -type  NoteProperty -name accessControlEntries -Value $aces
$aclObject | Add-Member -type  NoteProperty -name merge -Value false
$aclObject | Add-Member -type  NoteProperty -name token -Value $token
$request = $aclObject | ConvertTo-Json
$result=((Invoke-RestMethod -Method POST -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -ContentType "application/json" -Uri "https://dev.azure.com/$accountname/_apis/accesscontrolentries/c788c23e-1b46-4162-8f5e-d7585343b5de?api-version=5.0-preview.1" -Body $request).value)
Write-Output ("Output")
Write-Output ($result | ConvertTo-Json)
}
}

Set-ACE -folderPath "/"

Enjoy !!