如何修改PowerShell脚本获取Azure DevOps最新成功构建编号
解决Azure DevOps获取最新成功构建编号的PowerShell脚本问题
问题描述
使用PowerShell脚本从Azure DevOps管道获取构建信息时,无法正确提取最新的成功构建编号(例如示例中的20231016.5),原脚本输出不符合预期。
原脚本
function fetchBuildNumber() { $pat ="<personal acess token>" $AzureDevOpsAuthenicationHeader = @{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($PAT)")) } $UriOrganization = "https://<rest_api>/_apis/build/builds?api-version=7.1-preview.7" $ProjectsResult = Invoke-RestMethod -Uri $UriOrganization -Method get -Headers $AzureDevOpsAuthenicationHeader Foreach ($buildResult in $ProjectsResult.value.result) { if ($buildResult.equals("succeeded")){ Write-Host $ProjectsResult.value.buildNumber } } } fetchBuildNumber
当前错误输出
@{_links=; properties=; tags=System.Object[]; validationResults=System.Object[]; plans=System.Object[]; triggerInfo=; id=223567; buildNumber=20231016.1; status=completed; result=succeeded; queueTime=2023-10-16T06:23:50.9273616Z; startTime=2023-10-16T06:23:58.4673447Z; finishTime=2023-10-16T06:24:10.4163032Z; url=https://<url>/<project>/b9f9d6e9-a99a-4c65-9c44-adf670a6fff3/_apis/build/Builds/223567; definition=; buildNumberRevision=1; project=; uri=vstfs:///Build/Build/223567; sourceBranch=refs/heads/master; sourceVersion=959c15fdf53e30a60ab9f1f95f050c07380248d6; queue=; priority=normal; reason=individualCI; requestedFor=; requestedBy=; lastChangedDate=2023-10-16T06:24:10.81Z; lastChangedBy=; orchestrationPlan=; logs=; repository=; retainedByRelease=False; triggeredByBuild=; appendCommitMessageToRunName=True} @{_links=; properties=; tags=System.Object[]; validationResults=System.Object[]; plans=System.Object[]; triggerInfo=; id=223566; buildNumber=20231016.5; status=completed; result=failed; queueTime=2023-10-16T06:22:53.8662857Z; startTime=2023-10-16T06:23:01.2164532Z; finishTime=2023-10-16T06:23:16.1320749Z; url=https://<url>/<project>/b9f9d6e9-a99a-4c65-9c44-adf670a6fff3/_apis/build/Builds/223566; definition=; buildNumberRevision=5; project=; uri=vstfs:///Build/Build/223566; sourceBranch=refs/heads/master; sourceVersion=482cfa62cea136463b7c8f10ccf174d9d78d7349; queue=; priority=normal; reason=individualCI; requestedFor=; requestedBy=; lastChangedDate=2023-10-16T06:23:16.603Z; lastChangedBy=; orchestrationPlan=; logs=; repository=; retainedByRelease=False; triggeredByBuild=; appendCommitMessageToRunName=True} @{_links=; properties=; tags=System.Object[]; validationResults=System.Object[]; plans=System.Object[]; triggerInfo=; id=223556; buildNumber=20231016.4; status=completed; result=failed; queueTime=2023-10-16T05:44:36.5531704Z; startTime=2023-10-16T05:44:43.9888586Z; finishTime=2023-10-16T05:45:00.6769804Z; url=https://<url>/<project>/b9f9d6e9-a99a-4c65-9c44-adf670a6fff3/_apis/build/Builds/223556; definition=; buildNumberRevision=4; project=; uri=vstfs:///Build/Build/223556; sourceBranch=refs/heads/master; sourceVersion=7c3708310a88b1074c5f455dd0a896ee2c532cf0; queue=; priority=normal; reason=manual; requestedFor=; requestedBy=; lastChangedDate=2023-10-16T05:45:00.933Z; lastChangedBy=; orchestrationPlan=; logs=; repository=; retainedByRelease=False; triggeredByBuild=; appendCommitMessageToRunName=True} @{_links=; properties=; tags=System.Object[]; validationResults=System.Object[]; plans=System.Object[]; triggerInfo=; id=223555; buildNumber=20231016.3; status=completed; result=failed; queueTime=2023-10-16T05:44:30.908171Z; startTime=2023-10-16T05:44:37.2857315Z; finishTime=2023-10-16T05:44:50.3619703Z; url=https://<url>/<project>/b9f9d6e9-a99a-4c65-9c44-adf670a6fff3/_apis/build/Builds/223555; definition=; buildNumberRevision=3; project=; uri=vstfs:///Build/Build/223555; sourceBranch=refs/heads/master; sourceVersion=7c3708310a88b1074c5f455dd0a896ee2c532cf0; queue=; priority=normal; reason=individualCI; requestedFor=; requestedBy=; lastChangedDate=2023-10-16T05:44:50.69Z; lastChangedBy=; orchestrationPlan=; logs=; repository=; retainedByRelease=False; triggeredByBuild=; appendCommitMessageToRunName=True} @{_links=; properties=; tags=System.Object[]; validationResults=System.Object[]; plans=System.Object[]; triggerInfo=; id=223552; buildNumber=20231016.2; status=completed; result=succeeded; queueTime=2023-10-16T05:38:42.0775965Z; startTime=2023-10-16T05:38:49.9645514Z; finishTime=2023-10-16T05:39:00.9177615Z; url=https://<url>/<project>/b9f9d6e9-a99a-4c65-9c44-adf670a6fff3/_apis/build/Builds/223552; definition=; buildNumberRevision=2; project=; uri=vstfs:///Build/Build/223552; sourceBranch=refs/heads/master; sourceVersion=01eae21771b801f4593aaf2605a017c86b93f45c; queue=; priority=normal; reason=individualCI; requestedFor=; requestedBy=; lastChangedDate=2023-10-16T05:39:01.27Z; lastChangedBy=; orchestrationPlan=; logs=; repository=; retainedByRelease=False; triggeredByBuild=; appendCommitMessageToRunName=True} @{_links=; properties=; tags=System.Object[]; validationResults=System.Object[]; plans=System.Object[]; triggerInfo=; id=223551; buildNumber=20231016.1; status=completed; result=succeeded; queueTime=2023-10-16T05:37:38.8167652Z; startTime=2023-10-16T05:37:46.3075953Z; finishTime=2023-10-16T05:37:58.4518333Z; url=https://<url>/<project>/b9f9d6e9-a99a-4c65-9c44-adf670a6fff3/_apis/build/Builds/223551; definition=; buildNumberRevision=1; project=; uri=vstfs:///Build/Build/223551; sourceBranch=refs/heads/master; sourceVersion=1d793ebd727867f1f0dfa76a569c593463236ce9; queue=; priority=normal; reason=individualCI; requestedFor=; requestedBy=; lastChangedDate=2023-10-16T05:37:58.893Z; lastChangedBy=; orchestrationPlan=; logs=; repository=; retainedByRelease=False; triggeredByBuild=; appendCommitMessageToRunName=True}
问题分析
原脚本存在三个核心问题:
- 遍历对象错误:
Foreach ($buildResult in $ProjectsResult.value.result)遍历的是所有构建的result属性值集合,而非完整的构建对象,无法精准关联对应构建的buildNumber。 - 输出逻辑错误:满足条件时输出
$ProjectsResult.value.buildNumber,这是所有构建的编号数组,而非当前匹配到的单个构建编号。 - 未处理排序:未按构建完成时间排序,无法定位到最新的成功构建。
修改后的脚本
方案1:本地筛选排序(兼容现有API请求)
function fetchBuildNumber() { $pat = "<personal acess token>" $AzureDevOpsAuthenicationHeader = @{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($PAT)")) } $UriOrganization = "https://<rest_api>/_apis/build/builds?api-version=7.1-preview.7" $ProjectsResult = Invoke-RestMethod -Uri $UriOrganization -Method Get -Headers $AzureDevOpsAuthenicationHeader # 筛选成功构建,按完成时间倒序排序,取第一个(最新的) $latestSuccessBuild = $ProjectsResult.value | Where-Object { $_.result -eq "succeeded" } | Sort-Object -Property finishTime -Descending | Select-Object -First 1 if ($latestSuccessBuild) { Write-Host "最新成功构建编号:$($latestSuccessBuild.buildNumber)" } else { Write-Host "未找到成功构建" } } fetchBuildNumber
方案2:API层面筛选优化(减少数据传输)
通过API参数直接让Azure DevOps返回已筛选、排序的结果,提升性能:
function fetchBuildNumber() { $pat = "<personal acess token>" $AzureDevOpsAuthenicationHeader = @{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($PAT)")) } # 添加参数:只返回成功构建、按完成时间倒序、仅取最新1条 $UriOrganization = "https://<rest_api>/_apis/build/builds?api-version=7.1-preview.7&resultFilter=succeeded&orderBy=finishTimeDesc&top=1" $latestSuccessBuild = Invoke-RestMethod -Uri $UriOrganization -Method Get -Headers $AzureDevOpsAuthenicationHeader if ($latestSuccessBuild.value.Count -gt 0) { Write-Host "最新成功构建编号:$($latestSuccessBuild.value[0].buildNumber)" } else { Write-Host "未找到成功构建" } } fetchBuildNumber
脚本说明
- 方案1:先获取所有构建数据,本地筛选成功构建并按完成时间倒序,取第一条即为最新成功构建,适合需要保留全量构建数据的场景。
- 方案2:通过API参数直接过滤、排序并返回单条结果,减少数据传输量,性能更优,适合仅需最新成功构建的场景。
内容的提问来源于stack exchange,提问作者Jyoti Prakash Mallick
相关产品推荐
相关产品推荐

