Updateing deliver plan to allow for all projects in organization - rest api or powershell

Diptesh Kumar 601 Reputation points
2025-05-16T03:24:44.1966667+00:00

I want to make allow"manage delivery plans" for all projects to a time on organization. Please suggest how it can be accomplished using API OR powershell script

User's image

Azure DevOps
{count} votes

1 answer

Sort by: Most helpful
  1. Bheemani Anji Babu 165 Reputation points Microsoft External Staff
    2025-05-17T12:52:48.4766667+00:00

    I tried this end-to-end approach in my test environment, which I succeeded in. Using a pipeline strategy, the agenda is to assign managed delivery plan across projects under the org. To assign this permission to all the projects in a single attempt, the UI approach will not work because it does not have much feature yet. However, we can do this by using REST API's make sure the personal access token needs to create and grant the appropriate permissions like Graph > Read Project and Team > Read

    Token Administration > Read & Manage Permissions To assign security roles, you also need:

    Security > Manage permissions or oken Administration > Manage

    Then directly define the YAML pipeline:

    delivery-plan-access.yml

    trigger: none
    pool:
      vmImage: ubuntu-latest
    variables:
      organization: 'XXX-XXX-Organization'
      userEmail: '******@XXX.com'
    steps:
    - task: PowerShell@2
      inputs:
        targetType: 'inline'
        script: |
          $organization = '$(organization)'
          $myEmail = '$(userEmail)'
          $pat = "$(System.AccessToken)"
          if (-not $pat) {
            exit 1
          }
          $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($pat)"))
          $headers = @{ Authorization = "Basic $base64AuthInfo" }
          Write-Host "Retrieving all projects for organization '$organization'..."
          $projectsUrl = "https://dev.azure.com/$organization/_apis/projects?api-version=7.0"
          $projectsResponse = Invoke-RestMethod -Uri $projectsUrl -Headers $headers
          $projects = $projectsResponse.value
          Write-Host "Total projects found: $($projects.Count)"
          Write-Host "Retrieving descriptor for user '$myEmail'..."
          $graphUrl = "https://vssps.dev.azure.com/$organization/_apis/graph/users?api-version=7.1-preview.1"
          $response = Invoke-RestMethod -Uri $graphUrl -Headers $headers
          $userEntry = $response.value | Where-Object { $_.principalName -eq $myEmail }
          if (-not $userEntry) {
            Write-Host "##vso[task.logissue type=error]Descriptor not found for user: $myEmail"
            exit 1
          }
          $userDescriptor = $userEntry.descriptor
          Write-Host "Descriptor found: $userDescriptor"
          $securityNamespaceId = "52d39943-cb85-4d7f-8fa8-c6baac873819"
          foreach ($project in $projects) {
            Write-Host "Applying permission to project: $($project.name)"
            $token = "Project/$($project.id)"
            $aclUrl = "https://dev.azure.com/$organization/_apis/accesscontrolentries/$securityNamespaceId?api-version=7.0"
            $ace = @{
              descriptor = $userDescriptor
              allow = 1
              deny = 0
            }
            $accessControlEntry = @{
              token = $token
              accessControlEntries = @($ace)
            }
            $body = @{
              accessControlEntries = @($accessControlEntry)
            } | ConvertTo-Json -Depth 5
            try {
              $result = Invoke-RestMethod -Uri $aclUrl -Headers $headers -Method Patch -ContentType "application/json" -Body $body
              Write-Host "Permission applied successfully to project: $($project.name)"
            } catch {
              $statusCode = $_.Exception.Response.StatusCode.value__
              $responseBody = ""
              try {
                $responseBody = (New-Object System.IO.StreamReader($_.Exception.Response.GetResponseStream())).ReadToEnd()
              } catch {
                $responseBody = "Failed to read error response."
              }
              Write-Host "Failed to apply permission to project: $($project.name)"
              Write-Host "Status Code: $statusCode"
              Write-Host "Response Body: $responseBody"
            }
          }
          Write-Host "Permission assignment process completed."
      env:
        System.AccessToken: $(System.AccessToken)
    

    Later, create a new pipeline along with the existing yml file delivery-plan-access.yml then store your token under variables by naming it System. AccessToken because System. AccessToken is a special OAuth token automatically provided by Azure Pipelines. Add your token value and then save and run the pipeline.

    Here is the output: image

    I have created three test projects under the same org after the pipeline executed the managed delivery plan has allowed successful entry into three projects at a single attempt.

    Here is the output for the permissions status: Screenshot 2025-05-17 164204 Screenshot 2025-05-17 163945 Screenshot 2025-05-17 164020

    Screenshot 2025-05-17 164115

    I hope this has been helpful! 

    If above is unclear and/or you are unsure about something add a comment below.

    Please click the answer as original posters help the community find answers faster by identifying the correct answer. User's image


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.