Return 来自字符串搜索的布尔值

Return boolean from string search

我正在尝试通过搜索 Get-ComplianceSearch 的输出 'Completed' 来 return TRUE。我下面的代码是一个简单的等待循环。但我不认为我 return 正确地输入了值,因为循环永远不会结束。我是 PowerShell 的新手。请协助或指导。

我正在使用 Powershell Core 7.1。没有错误,但搜索字符串条件永远不会 returns TRUE。

    try {
        $timer = [Diagnostics.Stopwatch]::StartNew()
        while (($timer.Elapsed.TotalSeconds -lt $Timeout) -and (-not (Get-ComplianceSearch - 
Identity $searchName | Select-String 'Completed' -SimpleMatch -Quiet))) {
        Start-Sleep -Seconds $RetryInterval
        $totalSecs = [math]::Round($timer.Elapsed.TotalSeconds, 0)
        Write-Verbose -Message "Still waiting for action to complete after [$totalSecs] 
seconds..."
        }
    $timer.Stop()
    if ($timer.Elapsed.TotalSeconds -gt $Timeout) {
        throw 'Action did not complete before timeout period.'
    } else {
        Write-Verbose -Message 'Action completed before timeout period.'
    }
} catch {
    Write-Error -Message $_.Exception.Message
}

(这是命令 Get-ComplianceSearch 的预期输出)

显示 Select-String 更好的选择,因为基于 OO 的过滤查询特定属性总是比搜索字符串表示形式更可靠。

就是说,对于快速和肮脏的交互式搜索,能够通过命令的格式化显示输出进行搜索 可以很方便,不幸的是,Select-String 默认 而不是 .


至于你试过的:

让你的Select-String work, you need to insert Out-String-StreamSelect-String调用之前,以确保for-display表示被发送通过管道,逐行。

# `oss` can be used in lieu of `Out-String -Stream` in PSv5+.
# `sls` can be used in lieu of `Select-String`.
Get-ComplianceSearch | Out-String -Stream | Select-String 'Completed' -SimpleMatch -Quiet

注:

  • 如果要搜索用于显示的表示形式而不是默认表示形式,您可以在 Out-String -Stream 段之前插入一个 Format-* cmdlet 调用;例如
    Get-Item / | Format-List * | Out-String -Stream | Select-String ... 将搜索 列表 表示 Get-Item 输出的对象的所有属性。

也许令人惊讶,Select-String does not search an input object's for-display representation, as you would see it in the console, using the rich formatting provided by PowerShell's display-formatting system.

相反,它执行简单的.ToString()字符串化,其结果通常没有帮助并且不能依赖于包含属性值。 (例如,
@{ foo = 'bar' } | Select-String foo 没有 按预期工作;相当于
@{ foo = 'bar' }.ToString() | Select-String foo 因此
'System.Collections.Hashtable' | Select-String foo

可以说,Select-String 应该始终默认搜索输入对象的格式化字符串表示:

  • PowerShell 版本 5 及更高版本(两个版本)附带 oss 便利函数这一事实证明了对这种行为的需求,它是 Out-String -Stream.

  • GitHub issue #10726 要求将 Select-String 的当前行为更改为默认搜索 显示字符串表示

好吧,你不想在这里使用 Select-String(尽管你 可以 ,请参阅@mklement0 的 ,查看对象属性通常是首选)。那是 returning 一个对象,你想检查 Status 属性 是否有 "Completed"。对 -not 子表达式进行以下更改:

(-not (Get-ComplianceSearch -Identity $searchName | Where-Object {
  $_.Status -eq 'Completed'
}))

以上内容可以放在一行上,但为了便于阅读,我将其拆分。


基本上,Select-String 查找字符串中的内容。但是,如果您正在寻找一个对象的特定值 属性,您可以使用 Where-Object 来测试一个条件,并使用 return 任何匹配该条件的对象。在这种情况下,我们想要 return 任何 Status'Completed' 的对象,因此我们可以在 if 语句中否定它。


您(或其他人)可能想知道这是如何工作的,因为 Where-Object return 匹配对象,而不是布尔值。答案是“真实”。 PowerShell 对象是“真实的”,这意味着任何东西都可以被评估为 [bool].

在大多数情况下,以下值的计算结果为 $false。我列出了一些依赖“真实”值时需要注意的陷阱:

  • 0的数值
    • 0 的字符串值计算为 $true
  • 空数组
  • 空字符串
    • 纯空格字符串或仅包含不可打印字符的字符串计算为 $true
  • $false
    • False 的字符串值计算为 $true

其他大部分都将计算为 $true。这也是为什么在检查变量是否为 $null 时比较运算符在语法上是可选的。尽管有时显式值检查是个好主意,因为比较运算符比较的是实际值,而不仅仅是变量“是”还是“不是”。

这如何应用于上面的表达式?简单的。 if 语句,始终将条件表达式视为 [bool],无需转换。此外,逻辑运算符和条件运算符也隐含了布尔比较。例如,$var = $obj$obj 分配给 $var,但
$var = $obj -eq $obj2$var = $obj -and $obj2 将分配 $true$false.


所以知道上面的内容,如果 Where-Object return 什么都没有,那就是 $false。如果它 return 是有形物体,它就是 $true