【问题标题】:PowerShell Where-Object not working as expected with square brackets [ ]PowerShell Where-Object 使用方括号 [ ] 无法按预期工作
【发布时间】:2021-02-10 10:25:10
【问题描述】:

我正在尝试使用 PowerShell 根据关键字匹配“[X]”(字面意思是用方括号括起来的 X)过滤掉结果(行)

Invoke-Command -ComputerName Server1 -ScriptBlock {Get-WindowsFeature} | Where-Object {$_.DisplayName -like "*[X]*"}

结果比预期的要大。我正在以任何顺序或组合选择包含 [、] 和 X 的结果。只要所有字符都在线。我正在使用不使用正则表达式的 -like 。我认为那是-match 的工作。删除通配符没有帮助。

在有人问之前,我为什么不过滤“installstate”属性。这是一个远程运行的旧 PowerShell 模块,似乎根本没有返回该属性,因此我别无选择,只能寻找一个明确的“[X]” 谢谢

【问题讨论】:

  • -like 进行通配符模式比较,而[X] 是一个特殊序列 - 更改为-like '*`[X`]*' 以查找文字字符串[X]
  • 谢谢,在看到你的评论之前我刚刚做了什么。但还是不行。这个根本不返回任何结果。谷歌揭示了 PowerShell 和方括号的各种怪癖。
  • 请注意我使用的是单引号 - 如果你使用双引号,你需要双转义:-like "*``[X``]*"
  • 确实注意到了。只是尝试用双引号来解决它,没有结果。

标签: powershell wildcard


【解决方案1】:

这里有两个问题:

如何过滤包含[X] 的字符串

如 cmets 中所述,PowerShell 中的通配符模式使用 [] 用于特殊目的(描述字符范围),因此您需要使用反引号转义括号:

PS ~> 'This string contains [X] somewhere' -like '*`[X`]*'
True

注意,反引号也是可扩展字符串中使用的转义字符,因此如果使用双引号,则需要对括号进行双重转义:

PS ~> 'This string contains [X] somewhere' -like "*``[X``]*"
True

或者,选择更简单的东西,比如古老的String.Contains()

'This string contains [X] somewhere'.Contains('[X]')

...或要求 PowerShell 为您转义您的参考字符串:

'This string contains [X] somewhere' -like "*$([WildcardPattern]::Escape('[X]'))*"

如何过滤来自Get-WindowsFeature 的输出

它不起作用的原因是漂亮的树状缩进和[X]/[ ] 指示符实际上并不是输出对象的一部分 - 它是由 PowerShell 的格式化子系统强加的并且仅在它作为格式化表格列出的输出时出现。

由于[X] 表示组件已“安装”,因此对基础数据的等效查询实际上是:

Invoke-Command -ComputerName Server1 -ScriptBlock {
    Get-WindowsFeature
} | Where-Object {$_.InstallState -eq "Installed"}

【讨论】:

  • 非常感谢您的详细解释。与此“旧”Get-WindowsFeature 命令关联的安装状态属性结果是“Installed”而不是“InstallState”。如果您通过管道输出到 Format-List,您可以看到它。
  • @NadimAJ 不客气!我只在Server 2016上测试过,你是说你需要做... |Where-Object {$_.Installed -eq 'Installed'}吗?如果您让我知道哪个操作系统版本,我会将其添加到答案中(您也可以suggest an edit):-)
  • 操作系统版本是 2008。对于 2012 及更高版本,该属性似乎是 InstallState
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-17
  • 1970-01-01
  • 2018-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多