In the Azure DevOps portal, I select a pipeline, then the [...] menu, then Delete.
I see a message asking:
Are you sure? This action cannot be undone. This will permanently
delete the pipeline 'vt3e (1)'. Deletion includes all builds and
associated artifacts.
I type in the pipeline name and click OK but the pipeline does not delete.
I have waited some hours.
[Update]
F12 in Chrome shows an error in the console:
ms.vss-build-web.common-library.__y__CePsj5f5zdcIK.min.js:18 Error:
One or more builds associated with the requested pipeline(s) are
retained by a release. The pipeline(s) and builds will not be deleted
[Update]
I am trying to follow the answer given by David D, but when I go to delete a release I get a message
VS402946: 'Release-8' cannot be deleted as it is currently deployed on
stage(s) Stage 1.
[update]
The issue is logged at Microsoft
If you have deleted the release in question, but you still get this error, the solve for it is:
Go to the build pipeline in question.
Under the 'Runs' tab, open each "run" individually
If a run is being retained, you'll see a white box at the top with verbiage like "This run has been retained forever by 82 (Pipeline)" and to right, you'll see a button "View Retention Releases". That's where you'll delete the one or more retention releases.
You'll have to go through each "run" and repeat this process
If that white box/button isn't visible, that particular run isn't retained. You can confirm so by clicking the three dots in the top right corner and selecting "view retention releases"
I was having the same problem and tried different browsers, platforms etc. I found that by removing each release manually under the releases tab, going back to build and then trying to delete the pipeline again worked for me.
I came on the same problem last week and I updated a script from someone to work with the 5.1 API. This script will run over all builds that are retained by a release pipeline. You will need some tweaking of you don't want that all your builds are removed from releases.
$tfsServerURL = "https://dev.azure.com/{organisation}"
$TFSProject = "{project}"
$AzureDevOpsPAT = "{token}"
$AzureDevOpsAuthenicationHeader = #{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($AzureDevOpsPAT)"))}
#Set to $true to update builds by settingretainingByRelease= false
$CorrectError = $true
$URL = "$($tfsServerURL)/$($TFSProject)"
Write-Output $URL
#Get all builddefinitions in Project
$Buildefinitions = (Invoke-RestMethod -Uri ($URL + '/_apis/build/definitions?api-version=5.1') -Method GET -UseDefaultCredentials -Headers $AzureDevOpsAuthenicationHeader).value
foreach($Builddefiniton in $Buildefinitions)
{
Write-Output "Searching in $($Builddefiniton.name) with id $($Builddefiniton.id)"
#Get Builds with keepforever = false and retainedByRelease = true
$Builds = (Invoke-RestMethod -Uri ($URL + '/_apis/build/builds?definitions=' + $Builddefiniton.id + '&api-version=5.1') -Method GET -UseDefaultCredentials -Headers $AzureDevOpsAuthenicationHeader).value | where {$_.keepForever -eq $False -and $_.retainedByRelease -eq $true}
#Get releases linked to the build
foreach ($build in $Builds)
{
If ($CorrectError)
{
Invoke-RestMethod -Uri ($URL + '/_apis/build/builds/'+ $build.id + '?api-version=5.1') -Method Patch -Body (ConvertTo-Json #{"retainedByRelease"='false'}) -UseDefaultCredentials -Headers $AzureDevOpsAuthenicationHeader -ContentType "application/json" | Out-Null
Write-Output "`tFixed"
}
}
}
The PowerShell script will first fetch all build pipelines, then fetch all builds that are not kept infinitely and are retained by a release. If the CorrectError is set to true the script will then try to switch the retainedByRelease flag to false.
After I ran this script I was able to remove my build pipeline.
enter image description hereenter image description hereI have facing same below issue
One or more builds associated with the requested pipeline(s) are retained by a release. The pipeline(s) and builds will not be deleted.
It is simple to solve this, just open the pipeline which you want to delete and if you have seen this in your pipeline just click on three dots [View Retention leases]and open the View retention leases and click on Remove all option and close the pop-up.[Run retention]. Once you perform this action you're now free to go and delete the pipeline which you want.
February 2022 Version of Script to delete a Build Pipeline including all Builds and Leases:
#Azure DevOps Personal Access Token
# https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows
$personalAccessToken = "<Enter your personal access token here>"
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($personalAccessToken)"))
$header = #{authorization = "Basic $token"}
$organization = "<Enter your Azure DevOps Organization here>"
$project = "<Enter your Project Name here>"
$pipelineName = "<Enter the Build Pipeline Definition Name to be deleted here>"
#Get all build definitions
# API: GET https://dev.azure.com/{organization}/{project}/_apis/build/definitions/{definitionId}?api-version=6.0
$url = "https://dev.azure.com/$organization/$project/_apis/build/definitions?api-version=6.0"
$allBuildDefinitions = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers $header
$allBuildDefinitions.value | Where-Object {$_.name -eq $pipelineName} | ForEach-Object {
Write-Host $_.id $_.name $_.queueStatus
# For debugging reasons, just to be sure that we don't delete the wrong build pipeline
if ( $_.name -ne $pipelineName ) {
return;
}
#Get all Builds for a Definition
# API: GET https://dev.azure.com/{organization}/{project}/_apis/build/builds?definitions={definitions}&queues={queues}&buildNumber={buildNumber}&minTime={minTime}&maxTime={maxTime}&requestedFor={requestedFor}&reasonFilter={reasonFilter}&statusFilter={statusFilter}&resultFilter={resultFilter}&tagFilters={tagFilters}&properties={properties}&$top={$top}&continuationToken={continuationToken}&maxBuildsPerDefinition={maxBuildsPerDefinition}&deletedFilter={deletedFilter}&queryOrder={queryOrder}&branchName={branchName}&buildIds={buildIds}&repositoryId={repositoryId}&repositoryType={repositoryType}&api-version=6.0
$url = "https://dev.azure.com/$organization/$project/_apis/build/builds?definitions=" + $_.id + "&api-version=6.0"
$allBuildsOfDefinition = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers $header
#Process each Build of Definition
$allBuildsOfDefinition.value | Where-Object {$_.retainedByRelease -eq "True"} | Sort-Object id | ForEach-Object {
#Report on retain status
Write-Host "Build Id:" $_.id " retainedByRelease:" $_.retainedByRelease
#Get all Retention Leases for this Build
# API: GET https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}/leases?api-version=7.1-preview.1
$url = "https://dev.azure.com/$organization/$project/_apis/build/builds/" + $_.id + "/leases?api-version=7.1-preview.1"
$allLeasesOfBuild = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers $header
#Delete each Lease of Build
$allLeasesOfBuild.value | ForEach-Object {
#Delete Lease
# API: DELETE https://dev.azure.com/{organization}/{project}/_apis/build/retention/leases?ids={ids}&api-version=7.1-preview.2
$url = "https://dev.azure.com/$organization/$project/_apis/build/retention/leases?ids=" + $_.leaseId + "&api-version=7.1-preview.2"
Invoke-RestMethod -Uri $url -Method Delete -ContentType "application/json" -Headers $header
#Report on Lease deleted
Write-Host "Lease Id:" $_.leaseId " deleted"
}
#Delete Build
# API: DELETE https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}?api-version=7.1-preview.7
$url = "https://dev.azure.com/$organization/$project/_apis/build/builds/" + $_.id + "?api-version=7.1-preview.7"
Invoke-RestMethod -Uri $url -Method Delete -ContentType "application/json" -Headers $header
#Report on Build deleted
Write-Host "Build Id:" $_.id " deleted"
}
#Delete the Build Definition
# API: DELETE https://dev.azure.com/{organization}/{project}/_apis/build/definitions/{definitionId}?api-version=6.0
$url = "https://dev.azure.com/$organization/$project/_apis/build/definitions/" + $_.id + "?api-version=6.0"
Invoke-RestMethod -Uri $url -Method Delete -ContentType "application/json" -Headers $header
Write-Host "Build Definition:" $pipelineName " (" $_.id ") deleted"
}
Write-Host "Habe fertig!"
I get the same error if I try to delete a pipeline:
One or more builds associated with the requested pipeline(s) are retained by a release. The pipeline(s) and builds will not be deleted.
On the pipelines page go to the Runs tab, should see a list of records. If you click on the three dots to the right of the row you should see an option to View retention leases. If you Remove All you should then be able to remove that row. You will then need to repeat this step for every row in the the runs tab until all runs have been deleted.
Only then will you be able to delete the parent pipeline.
Microsoft now has an api to delete leases directly.
DELETE https://dev.azure.com/{organization}/{project}/_apis/build/retention/leases?ids={ids}&api-version=6.0-preview.1
https://learn.microsoft.com/en-us/rest/api/azure/devops/build/leases/delete?view=azure-devops-rest-6.0
How to:
Enumerate build definitions
Delete leases for each desired build definition
Delete the build definition
Example:
$organization = "flintsones"
$project = "feed-dino"
$personalAccessToken = "****************"
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($personalAccessToken)"))
$header = #{authorization = "Basic $token"}
function DeleteLease($definitionId) {
$url = "https://dev.azure.com/$organization/$project/_apis/build/retention/leases?api-version=6.0-preview.1&definitionId=$definitionId"
$leases = (Invoke-RestMethod -Method GET -Uri $url -ContentType "application/json" -Headers $header )
foreach ($lease in $leases.value) {
$leaseId = $lease.leaseId
$url = "https://dev.azure.com/$organization/$project/_apis/build/retention/leases?ids=$($leaseId)&api-version=6.0-preview.1"
$ignore = Invoke-RestMethod -Method DELETE -Uri $url -ContentType "application/json" -Headers $header
}
}
$url = "https://dev.azure.com/$organization/$project/_apis/build/definitions?api-version=3.2"
Write-Host $url
$buildDefinitions = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers $header
foreach ($def in $builddefinitions.value) {
Write-Host $def.id $def.queueStatus $def.name
DeleteLease $def.id
}
Go to pipeline runs and click on 3 dots when you hover across each run. You will see an option for view retention leases. Click on that and then click on remove all.
You have to do it for all the runs.
Once deleted then try to delete the build pipeline.
I used powershell to delete just my own build (instead of looping through all the build definitions)
$organization = "YourOrganization"
$project = "YourProject"
$personalAccessToken = "GetTokenFromAzureDevops"
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($personalAccessToken)"))
$header = #{authorization = "Basic $token"}
$url = "https://dev.azure.com/$organization/$project/_apis/build/definitions?api-version=3.2"
Write-Host $url
$buildDefinitions = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers $header
function DeleteLease($definitionId) {
$url = "https://dev.azure.com/$organization/$project/_apis/build/retention/leases?api-version=6.0-preview.1&definitionId=$definitionId"
$leases = (Invoke-RestMethod -Method GET -Uri $url -ContentType "application/json" -Headers $header )
foreach ($lease in $leases.value) {
$leaseId = $lease.leaseId
$url = "https://dev.azure.com/$organization/$project/_apis/build/retention/leases?ids=$($leaseId)&api-version=6.0-preview.1"
$ignore = Invoke-RestMethod -Method DELETE -Uri $url -ContentType "application/json" -Headers $header
}
}
DeleteLease "yourBuildDefinitionId"
Note :
The PAT token can be created from Azure Devops Portal using below
Sign in to your organization in Azure DevOps (https://dev.azure.com/{yourorganization})
From your home page, open your user settings, and then select Personal access tokens.
To get the build definition Id- see the URL of build , it will have the ID in the URL itself.
To fix that problem you can:
clone failed stage in the current release pipeline configuration
delete the original stage and use a clone instead of a deleted stage with a different name.
delete the previous failed release (*it will be possible)
after deleting you can rename the copied stage again.
enjoy
Go to the pipeline, and check retention for each run, and if found delete them.
This did solve my problem of deleting a pipeline.
You can also just temporarily choose to retain nothing, then delete what you want, then revert.
You just need to click on three dots menu button and select delete then it will make sure that you know what you are actually doing, check the "
Automatically cancel any in-progress release deployments" and remove it
Related
We have a task/job during our release pipeline that we would like to skip in the event that files haven't changed in a particular folder in our repo. I am able to get a powershell script task to change a variable to skip the following task properly, but I don't know how I can do the actual comparison to determine whether to skip or not.
How can I compare changes via git or some other way to see if files have changed in a particular folder since the last release? Is it possible to compare the current artifact to the last deployed artifact in some way?
Is it possible to compare the current artifact to the last deployed artifact in some way?
Yes. We can add a PowerShell task and run Rest APIs to compare the artifacts and get the changes files.
Here is an PowerShell example:
$token = "$(PAT)"
$url=" https://vsrm.dev.azure.com/OrgName/ProjectName/_apis/release/deployments?definitionId=releasedefinitionid&deploymentStatus=succeeded&definitionEnvironmentId=releasedefinitionenvironmentid&api-version=6.0"
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($token)"))
$response = Invoke-RestMethod -Uri $url -Headers #{Authorization = "Basic $token"} -Method Get -ContentType application/json
echo $response.value[0].release.id
$lastreleaseid = $response.value[0].release.id
$url1 ="https://vsrm.dev.azure.com/OrgName/ProjectName/_apis/Release/releases/$(RELEASE.RELEASEID)/changes?baseReleaseId=$($lastreleaseid)&%24top=2500&artifactAlias=Artifacts Alias name&api-version=7.1-preview.1"
$response1 = Invoke-RestMethod -Uri $url1 -Headers #{Authorization = "Basic $token"} -Method Get -ContentType application/json
$count = 0
Foreach ($commitid in $response1.value.id)
{
echo $commitid
$url2 = "https://dev.azure.com/OrgName/_apis/git/repositories/RepoId/commits/$($commitid)/changes?api-version=7.0"
$response2 = Invoke-RestMethod -Uri $url2 -Headers #{Authorization = "Basic $token"} -Method Get -ContentType application/json
Foreach ($changefile in $response2.changes)
{
$filepath= $changefile.item.path
if($filepath -like '/test*')
{
$count = $count + 1
}
}
}
echo $count
if($count -gt 0 )
{
echo "##vso[task.setvariable variable=one]secondValue"
}
Explanation:
Step1: We can use the Rest API:Deployments - List to get the last successful Release of the Release environmen.
Step2: We can use the following Rest API to get the commits between two release.
Get https://vsrm.dev.azure.com/OrgName/ProjectName/_apis/Release/releases/currentreleaseid/changes?baseReleaseId=comparereleaseid&%24top=2500&artifactAlias=Artifacts Alias name&api-version=7.1-preview.1
Step3: We can get the changed files of the commits via the Rest API: Commits - Get Changes
Finally, we can set the Pipeline variable based on the result of the API response.
Result:
I'm trying to delete jobs from my queue. I didn't see cancel button at the time so I decided to delete build. After that I can't cancel or delete stucked jobs at queue. I don't have experience with rest api but tried bulk queue remove powershell script. It removes every job in queue except stucked ones.
I've tried to bulk queue delete script
$PATToken = "************************"
$AuthHeader= #{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($PATToken)")) }
$azureDevops = "https://dev.azure.com//*****"
$BuildsUrl = "$azureDevops/_apis/build/builds"
$filterBuilds = "$($BuildsUrl)?statusFilter=notStarted&api-version=6.0"
(Invoke-RestMethod -Method Get -Uri $filterBuilds -Headers $AuthHeader).value | % {
$uri = "$($BuildsUrl)/$($.id)?api-version=6.0" # Azure Devops URI
$body = '{"status":4}' # body
$result = Invoke-RestMethod -Method Patch -Uri $uri -Headers $AuthHeader -ContentType 'application/json' -Body $body -Verbose #cancel build
Write-Output "$($.definition.name) cancaled"
}
For easy use of REST API, you can use Postman.
Firstly, you can use this REST API Builds - Get to check the status and the result of your target build.
GET https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}?api-version=6.0
If your pipeline is still running, the status is inProgress.
If your build is deleted while running, the status will be completed and the result will be canceled.
At the same time, you will see information about the build being deleted, such as the date of deletion, who deleted it, and the reason for deletion.
Secondly, if the result obtained through the above REST API is that your build is still running, you can cancel the build through the REST API Builds - Update Build.
PATCH https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}?api-version=6.0
The request body should be:
{
"status": "cancelling"
}
The Powershell scripts for your reference:
$token = "<Your PAT>"
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($token)"))
$url="https://dev.azure.com/<org name>/<project name>/_apis/build/builds/<build id>?api-version=6.0"
$body = #'
{
"status": "cancelling"
}
'#
$head = #{ Authorization =" Basic $token" }
$response = Invoke-RestMethod -Uri $url -Method PATCH -Headers $head -Body $body -ContentType application/json
$response | ConvertTo-Json
I have azure DevOps release and I would like to delete release variables post one stage of deployment. could you please provide some pointers on how to do this? I know how to update the value of the variable using API but am unable to delete the variable. Any pointers are highly appreciated
To delete the release pipeline variable during the release process, you could use the Definitions - Update Rest API.
Here is the PowerShell example:
$url = "$($env:SYSTEM_TEAMFOUNDATIONSERVERURI)$env:SYSTEM_TEAMPROJECTID/_apis/Release/definitions/$($env:RELEASE_DEFINITIONID)?api-version=5.0-preview.3"
Write-Host "URL: $url"
$pipeline = Invoke-RestMethod -Uri $url -Headers #{
Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
}
$pipeline.variables.PSObject.Properties.Remove('variablename')
####****************** update the modified object **************************
$json = #($pipeline) | ConvertTo-Json -Depth 99
$updatedef = Invoke-RestMethod -Uri $url -Method Put -Body $json -ContentType "application/json" -Headers #{Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"}
write-host "=========================================================="
Write-host "The value of Varialbe 'test' is deleted"
write-host "=========================================================="
The following code is used to delete the variable.
$pipeline.variables.PSObject.Properties.Remove('variablename')
For more detailed info, you could refer to this ticket: How to modify Azure DevOps release definition variable from a release task?
As part of our release pipeline we have a task (the last task) to merge the release branch back to master.
I was wondering whether there is a way to check that this task or the previous release has completed before allowing the new release to be queued. Can a gate be used for this?
Ideally, the release manager would then be able to decide whether they want to continue with the release or to cancel.
You can't use the Invoke Rest API gate with an Azure DevOps API url because for checking the last release status you need to check the environment (stage) status, and for this, you need to the release id (so you can't know what it will be and put it in the rest API gate URL).
But, you can use PowerShell to check the last release and if it is not succeeded just fail the stage.
Add a PowerShell task in your release to check the last release:
$headers = #{ Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN" }
# Replace {org} with your organization
# Replace {project} with your project
# Replace {defId} with your release definition id
$url = "https://vsrm.dev.azure.com/{org}/{project}/_apis/release/releases?definitionId={defId}&api-version=5.1"
$releases = Invoke-RestMethod -Method Get -Uri $url -Headers $headers -ContentType 'application/json'
$releaseUrl = "https://vsrm.dev.azure.com/{org}/{project}/_apis/release/releases/$($releases.value[1].id)?api-version=5.1"
$releaseInfo = Invoke-RestMethod -Method Get -Uri $releaseUrl -Headers $headers -ContentType 'application/json'
$releaseEvnriomentId = $releaseInfo.environments.Where({ $_.name -eq 'THE STAGE NAME WHERE YOU DO MERGE' }).id
$envUrl = "https://vsrm.dev.azure.com/{org}/{project}/_apis/Release/releases/$($releases.value[1].id)/environments/$($releaseEvnriomentId)?api-version=5.1-preview.1"
$environment = Invoke-RestMethod -Method Get -Uri $envUrl -Headers $headers -ContentType 'application/json'
$envStatus = $environment.status
if($envStatus -ne "succeeded")
{
Write-Error "Previous release not succeeded!"
}
else
{
Write-Host "Previous release succeeded :)"
}
In the agent job options you need to allow scripts to access the OAuth token:
Azure functions also support PowerShell so you do it also with Azure functions gate:
1) Create a new Azure Function with VS Code like explained here.
2) In your run.ps1 file replace the code to this code:
using namespace System.Net
# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)
# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."
$defnitionId = $Request.Query.DefinitionId
# Generate PAT and put it in the {YOUR PAT}
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,"{YOUR PAT}")))
$headers = #{Authorization=("Basic {0}" -f $base64AuthInfo)}
# Replace {org} with your organization
# Replace {project} with your project
$url = "https://vsrm.dev.azure.com/{org}/{project}/_apis/release/releases?definitionId=$($defnitionId)&api-version=5.1"
$releases = Invoke-RestMethod -Method Get -Uri $url -Headers $headers -ContentType 'application/json'
Write-Debug $releases
$releaseUrl = "https://vsrm.dev.azure.com/{org}/{project}/_apis/release/releases/$($releases.value[1].id)?api-version=5.1"
$releaseInfo = Invoke-RestMethod -Method Get -Uri $releaseUrl -Headers $headers -ContentType 'application/json'
Write-Debug $releaseInfo
$releaseEvnriomentId = $releaseInfo.environments.Where({ $_.name -eq 'THE STAGE NAME WHERE YOU DO MERGE' }).id
$envUrl = "https://vsrm.dev.azure.com/{org}/{project}/_apis/Release/releases/$($releases.value[1].id)/environments/$($releaseEvnriomentId)?api-version=5.1-preview.1"
$environment = Invoke-RestMethod -Method Get -Uri $envUrl -Headers $headers -ContentType 'application/json'
Write-Debug $environment
$envStatus = $environment.status
Write-Debug $envStatus
if($envStatus -ne "succeeded")
{
$status = [HttpStatusCode]::BadRequest
$body = "failed"
}
else
{
$status = [HttpStatusCode]::OK
$body = "success"
}
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]#{
StatusCode = $status
Body = $body
})
3) Publish the function to Azure.
4) Create an Invoke Azure Function gate in your release:
Another option, take the above code, convert him to C# or another language ans use Rest API, deploy to it web server and use the Invoke Rest API gate.
Due to long running builds various next in line builds take longer time to execute.
Is there a way I can cancel and delete waiting build in queue and give way for latest triggered build using PowerShell or REST API's?
The following code snippet goes over all TFS builds,Gets the Builds which in Progress and not started, and then, cancel them.
$tfsUrl = "http://{server}:{port}/{organization}/{collection}/{project}" # TFS Base URL
$BuildDefsUrl = "$tfsUrl/_apis/build/definitions?api-version=2.0" # TFS build definitions URL
$BuildsUrl = "$tfsUrl/_apis/build/builds" #TFS Builds URL
$Builds = (Invoke-RestMethod -Uri ($BuildDefsUrl) -Method GET -UseDefaultCredentials).value | Select id,name # get all builds
#for filtering use : | Where-Object {$_.name -like "*Your Pattern*"}
foreach($Build in $Builds)
{
$command = "$($BuildsUrl)?api-version=3.2-preview.3&resultFilter=inprogress&definitions=$($Build.id)&queryOrder=finishTimeDescending"
$Ids = (((Invoke-RestMethod -Method Get -Uri $command -UseDefaultCredentials).value) | where status -like "*notStarted*").id # get waiting builds id's
foreach($id in $Ids)
{
$uri = "$($BuildsUrl)/$($id)?api-version=2.0" # TFS URI
$body = '{"status":4}' # body
$result = Invoke-RestMethod -Method Patch -Uri $uri -UseDefaultCredentials -ContentType 'application/json' -Body $body -Verbose #cancel build
}
}
The above example is pretty old. The code snippet below working for Azure Devops-
$PATToken = "PAT_GOES_HERE"
$AuthHeader= #{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($PATToken)")) }
$azureDevops = "https://dev.azure.com/{organization}/{project}"
$BuildsUrl = "$azureDevops/_apis/build/builds"
$filterBuilds = "$($BuildsUrl)?statusFilter=notStarted&api-version=6.0"
(Invoke-RestMethod -Method Get -Uri $filterBuilds -Headers $AuthHeader).value | % {
$uri = "$($BuildsUrl)/$($_.id)?api-version=6.0" # Azure Devops URI
$body = '{"status":4}' # body
$result = Invoke-RestMethod -Method Patch -Uri $uri -Headers $AuthHeader -ContentType 'application/json' -Body $body -Verbose #cancel build
Write-Output "$($_.definition.name) cancaled"
}