基本上我想在PowerShell中这样做。
Get-ADOrganizationalUnit -SearchBase "OU=myOU,DC=domain,DC=biz" -Filter {name -eq "_Computer" -or name -eq "_Devices"}
但是,我想在数组中声明字符串,因为我更需要它们。
很容易说,我想这样做。但是,当然,它不起作用!
$Strings = @("_Computer", "_Devices")
Get-ADOrganizationalUnit -SearchBase "OU=myOU,DC=domain,DC=biz" -Filter {name -eq $Strings}
答案 0 :(得分:2)
最方便的解决方案是使用全部检索-Filter
参数(-Filter *
)然后通过管道传输到{{1} } cmdlet,它允许使用Where-Object
运算符来测试数组包含(PSv3 +):
-in
需要使用单独的Get-ADOrganizationalUnit -SearchBase "OU=myOU,DC=domain,DC=biz" -Filter * |
Where-Object name -in $Strings
来电,因为AD cmdlet' Where-Object
参数不支持-Filter
运算符 - 了解解释-in
参数的目标cmdlet而非PowerShell非常重要。
但是,请注意,此便利性具有严重的性能影响 :使用-Filter
参数通常比将未过滤的检索与未过滤检索相结合更快,更有效稍后在PowerShell 中过滤,因为-Filter
在源过滤 - 请参阅this answer了解基于-Filter
的解决方案和背景信息。
答案 1 :(得分:2)
<强> TL;博士强>
AD cmdlet的-Filter
参数不支持-in
(数组包含)运算符,因此-Filter { name -in $Strings }
不是选项 - 见about_ActiveDirectory_Filter。
使用Where-Object
的管道是一个选项,如Martin Brandl's answer - 让 PowerShell 进行过滤之后,在未经过滤的检索之后 - 它将比使用-Filter
慢得多且效率低。
要使用-Filter
,请将过滤器合成为字符串(事实上, ),以模拟-in
来自与-eq
加入的-or
个表达式数组:
# Sample organizational unit names.
$Strings = @("_Computer", "_Devices")
# Construct the filter string; with the sample input, this yields a single
# string with the following content:
# Name -eq "_Computer" -or Name -eq "_Devices"
$Filter = ($Strings | ForEach-Object { "Name -eq `"$_`"" }) -join ' -or '
#`# Pass the filter string to the AD cmdlet.
Get-ADOrganizationalUnit -SearchBase "OU=myOU,DC=domain,DC=biz" -Filter $Filter
-Filter
参数由目标cmdlet 解释,而不是 PowerShell 。
过滤器的语法由目标cmdlet 规定,该语法可能是也可能不是PowerShell- ,如,并且可以从cmdlet到cmdlet不等(组)。
您必须查阅目标cmdlet的文档以了解要使用的语法 - 不要假设您可以传递包含PowerShell表达式的任意脚本块;例如:
诸如Get-ADOrganizationalUnit
之类的AD cmdlet支持非常有限的特定于域的表达式语言,该语言使用PowerShell- 之类的语法,但有许多怪癖和异常 - 请参阅{{3 }}
相比之下,与Get-ChildItem
等文件系统提供程序相关的cmdlet仅支持单个通配符表达式作为-Filter
参数,例如*.txt
,以及特定的通配符 - 表达式方言与PowerShell自身甚至平台相关的不同 - 请参阅我的about_ActiveDirectory_Filter。
尽管存在局限性且缺乏直接的PowerShell集成,但过滤器具有一个重要优势:它们在源过滤对象,这样可以更快,更有效地检索> strong>与未经过滤的检索相比,通过管道传输到PowerShell的Where-Object
cmdlet进行以后过滤。
过滤器在技术上是字符串([string]
个实例)。
最好构造并将作为字符串传递给它们,而不是PowerShell 脚本块。
虽然传递脚本块似乎很方便,尤其是为了简化引用,它有陷阱,因为脚本块总是被转换为{{1 }}:
脚本块的字符串表示形式只是开头[string]
和结束{
之间的字符串,原样,包括空格。例如,这意味着脚本块}
变为文字内容为{ name -eq $var }
的字符串 - 换句话说: name -eq $var
未插值< / EM>
当 AD cmdlet时,似乎确实应用了一轮额外的字符串插值 [1]
得到的文字 - 例如$var
不正确 - 即使有陷阱:
Get-ChildItem
等脚本块将不工作,因为访问变量的属性 不直接工作插值字符串(使用{ name -eq $someObj.Name }
,子表达式运算符是必需的 - 请参阅我的this answer作为背景信息。
使用隐式远程处理,这一额外的字符串插值可能会发生远程,其中本地变量无法访问。
可能会给人以错误的印象,即支持常规的PowerShell表达式。
[1]这是我从观察到的行为中推断的。请告诉我们您是否了解更多/知道此推断是不正确的。