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 多个条件不起作用的主要内容,如果未能解决你的问题,请参考以下文章

laravel 5.8中的多个Where条件不起作用

具有多个条件但 @WhereJoinTable 不起作用的休眠连接表

与当前日期比较时,通过多个元键查询帖子不起作用

动态菜单活动不起作用? (如果条件不起作用)

有条件的分配,为啥它不起作用?

为啥 SSI 条件!= || != 不起作用?