Powershell where-object 复杂逻辑

Powershell where-object complex logic

我无法想出使用 PowerShell 中的 where 对象执行复杂逻辑的方法

我有以下代码,但是将 and 与 ors 分开并没有按预期工作。

Get-ADComputer -Filter * | Where-Object {($_.Enabled) -and
                                    (($_.DistinguishedName -Contains "world") -or
                                        ($_.DistinguishedName -Contains "foo")) -and
                                        (($_.SID -Contains "bar") -or
                                        ($_.SID-Contains "something else"))}

如果我在 c# 中这样做,我会得到结果,但在 powershell 中我不会。

关于如何解决这个问题有什么想法吗?

TIA

这不是答案 - 所以请在您阅读后告诉我,以便我删除它。

这是您的代码,缩进了更多信息,删除了不必要的额外括号,并在运算符周围留有空格。

Get-ADComputer -Filter * |
    Where-Object {
        $_.Enabled -and
        ($_.DistinguishedName -Contains "world" -or
            $_.DistinguishedName -Contains "foo") -and
        ($_.SID -Contains "bar" -or
            $_.SID -Contains "something else")
        }

请注意,-contains 运算符不适用于字符串……它适用于集合中的成员资格。如果要针对字符串进行测试,请使用 -match.Contains() 或带通配符的 -like

这就是您使用 AD PS 模块执行查询的方式:

Get-ADComputer -LDAPFilter "(!userAccountControl:1.2.840.113556.1.4.803:=2)"|where-object{
    $_.DistinguishedName -match 'World|Foo' -and $_.SID -match 'bar|something else'
}
  • -LDAPFilter "(!userAccountControl:1.2.840.113556.1.4.803:=2)" = 已启用计算机 Object
  • -match 允许使用正则表达式,你可以像 OR.
  • 那样使用管道

-contains 是用于在数组中查找项目的运算符。示例:

PS /> @(
'apple'
'banana'
'pineapple'
) -contains 'apple'

True

此外,正如 Dave Wyatt 不久前在 powershell.org 上的一个很好的 post 中指出的那样,您可能希望尽可能避免使用 where-object,因为它是最慢的过滤方式collections。它唯一的优点是低内存消耗和流水线。 以下是一些更快高效代码的示例:

#Example 1:
$computers=Get-ADComputer -LDAPFilter "(!userAccountControl:1.2.840.113556.1.4.803:=2)"
$collection=[system.collections.generic.list[Microsoft.ActiveDirectory.Management.ADComputer]]::new()

foreach($computer in $computers)
{
    if($computer.DistinguishedName -match 'World|Foo' -and $computer.SID -match 'bar|something else')
    {
        $collection.add($computer)
    }
}

#Example 2:
filter myFilter{
    if($_.DistinguishedName -match 'World|Foo' -and $_.SID -match 'bar|something else')
    {
        $_
    }
}

$computers=Get-ADComputer -LDAPFilter "(!userAccountControl:1.2.840.113556.1.4.803:=2)"|myFilter

#Example 3
$computers=(Get-ADComputer -LDAPFilter "(!userAccountControl:1.2.840.113556.1.4.803:=2)").where({
    $_.DistinguishedName -match 'World|Foo' -and $_.SID -match 'bar|something else'  
})

关于 PowerShell 上 Collections 的不同过滤方式及其在 Google 上的优缺点的信息很多。