我正在尝试过滤掉特定组中的用户。
我在变量中得到以下输出:
Group1
Group2
etc...
保存在数组中的每行的一组。我试图只过滤出一个特定的组。但是当我使用-contains
时,它总是会说$false
,即使在该小组中也是如此。
我的代码:
$group = get-aduser -identity name -properties memberof |
select-object -expandproperty memberof | %{ (get-adgroup $_).name }
$contains = $group -contains "string"
$contains
为$false
,即使数组中的元素包含字符串...
我想念什么?
答案 0 :(得分:2)
您的误解是您希望PowerShell的-contains
operator对LHS数组的元素执行 substring 匹配。
相反,它像数组-eq
一样对数组元素进行平等测试-有关详细信息,请参见this answer。
要针对数组的元素 执行文字子字符串匹配,请使用:
# With non-literal search strings:
[bool] $contains = $group -match ([regex]::Escape($someString))
# With a string literal that doesn't contain regex metachars.,
# escaping isn't needed.
[bool] $contains = $group -match 'foo'
# With a string literal with metachars., you must individually \-escape them.
[bool] $contains = $group -match 'foo\.bar'
注意:
上面显示了一种可靠的通用方法,可确保使用[regex]::Escape()
将搜索字符串视为 literal 值,这是必需的,因为 {{1 }}期望 regex (regular expression)作为其RHS(搜索模式)。
转义并非总是必要的;具体来说,只有存在所谓的元字符(那些在正则表达式中具有特殊含义的字符,例如-match
)才需要它,并且当您使用字符串 literal 时,可以选择直接.
转义;例如,要搜索文字子串\
,您可以传递a.b
。
与PowerShell中的所有运算符一样,默认情况下,匹配不区分大小写 ;使用'a\.b'
变体进行区分大小写的匹配。
上面约束的-cmatch
类型用于确保将[bool]
操作的结果转换为布尔值:
-match
直接返回带有标量(非数组)LHS的布尔值,而带有 array LHS的布尔值则充当 >过滤器,并返回匹配数组元素 ;在布尔上下文中(例如在-match
条件中)进行解释,通常仍能得到预期的结果,因为非空数组被解释为if
,而空数组则被解释为$true
;再次,但是重要的是要知道区别。这在实践中很少会涉及性能,但是值得注意的是, $false
由于用作数组的过滤器,总是与 all 数组元素-一旦找到 first 匹配项,它就不会停止,就像-match
和-contains
运算符那样。
-in
来获取匹配的元素本身。对-match
执行 substring 匹配的错误期望可能是由于与类似命名但无关的String.Contains()
方法的混淆引起的,它确实执行文字 substring 匹配;例如,-contains
产生'foo'.Contains('o')
。另外请注意,$true
默认情况下区分大小写 。
PowerShell具有 no 运算符,用于 literal 子字符串匹配。
但是,您可以将PowerShell的通用数组过滤功能与.Contains()
字符串方法结合使用-但请注意,这通常会(可能会)比.Contains()
方法更糟糕。
合理执行的替代方法是使用PSv4 + -match
数组方法,如下所示:
.Where()
从好的方面来说,一旦找到第一个匹配项,此方法就会停止匹配。
答案 1 :(得分:-1)
答案是-match
插入了contains
。现在输出为true。