Where-Object 多个条件不起作用
Posted
技术标签:
【中文标题】Where-Object 多个条件不起作用【英文标题】:Where-Object multiple conditions not working 【发布时间】:2022-01-04 02:12:02 【问题描述】:我正在尝试使用特定定义中的模板参数获取所有正在运行的构建(正在进行中)+。我在 Azure DevOps 中使用 Powershell@2 任务来完成此任务,但没有使用 Where-Object 运行多个条件。下面是代码:
$token = "123"
$organization = "foo"
$project = "abc"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("0:1" -f $user,$token)))
$ThisBuildDefinitionID = "8430"
[int]$ThisBuildID = "1571327"
$GET_BUILDS_BY_DEFINITION_URL = "https://azure.com/$organization/$project/_apis/build/builds?api-version=6.0&definitions=$ThisBuildDefinitionID"
do
$GET_BUILDS_BY_DEFINITION_RESPONSE = ""
try
$GET_BUILDS_BY_DEFINITION_RESPONSE = Invoke-RestMethod -Uri $GET_BUILDS_BY_DEFINITION_URL `
-Method GET `
-ContentType "application/json" `
-Headers @Authorization=("Basic 0" -f $base64AuthInfo)
catch
continue
Write-Host $GET_BUILDS_BY_DEFINITION_RESPONSE.value
[array]$runningBuilds = $GET_BUILDS_BY_DEFINITION_RESPONSE.value | Where-Object "status" -eq "inProgress" -and "templateParameters.param1" -eq "myparam"
Write-Host "running builds count: " $runningBuilds.count
if ($runningBuilds.count -gt 0)
[int]$currentRunningBuild = ($runningBuilds | Sort-Object -Property "Id")[0].Id
Write-Host "This Build ID: " $ThisBuildID
Write-Host "Currently Running Build ID: " $currentRunningBuild
Write-Host "Waiting..."
Write-Output ""
Start-Sleep -Seconds 5
while($ThisBuildID -ne $currentRunningBuild)
Write-Host "Waiting Complete."
Write-Host "Starting Build: " $ThisBuildID
Start-Sleep -Seconds 5
Where-Object "status" -eq "inProgress" -and "templateParameters.param1" -eq "myparam"
是我遇到问题的部分,即什么条件才能正常运行。
当我只使用像 Where-Object "status" -eq "inProgress"
这样的单一条件时,它可以正常工作并让我获得正在进行的构建,但我还想包含一个模板参数条件
有人可以帮我解决我做错了什么吗?
PS:感谢 visualstudio 开发者社区中的Devin Lambert's script。
【问题讨论】:
我查看了这个 API 的文档,我很惊讶它完全可以工作,因为我没有看到这个 API 返回的 Build 类的“值”属性。但除此之外,如果您尝试对子属性应用过滤器,那么您可以使用类似? status -eq "inProgress" | ? $_.templateParameters.param1 -eq "myparam"
的东西,您可以一次性完成所有操作,但这只是我的偏好,当它不会分离时对性能产生很大影响。
【参考方案1】:
Where-Object "status" -eq "inProgress" -and "templateParameters.param1" -eq "myparam"
您正在比较(不同的)字符串字面量,而您大概的意思是将 属性值 与字符串字面量进行比较。
您需要automatic $_
variable 来引用script block ( ...
) 中手头的管道输入对象,这允许您访问其属性:
Where-Object
$_.status -eq "inProgress" -and $_.templateParameters.param1 -eq "myparam"
请注意,Where-Object
(以及ForEach-Object
)也支持simplified syntax,您不需要脚本块并且$_
的使用是隐含的,但这语法限于:
一个单个条件
非嵌套属性访问。
因此,在您的情况下,它的使用不是一个选项。
只有 first -eq
比较,它对 immediate status
属性的访问只能用简单的语法表示(如您在问题中所示) :
# Equivalent of:
# Where-Object $_.status -eq 'inProgress'
# 'status' binds positionally to the -Property parameter.
Where-Object status -eq 'inProgress'
相比之下,嵌套属性访问不起作用:
# !! Does NOT work as intended.
Where-Object templateParameters.param1 -eq 'myparam'
原因是templateParameters.param1
,它在位置上绑定到-Property
参数,作为一个整体被解释为单个属性的名称。 p>
虽然 链接 多个 simple-syntax Where-Object
调用可能是值得的,以方便语法,但在您的情况下,您必须将简单语法与正则语法调用,在这种情况下,您不妨坚持原来的单一正则语法方法。
【讨论】:
以上是关于Where-Object 多个条件不起作用的主要内容,如果未能解决你的问题,请参考以下文章