我正在努力处理带有包含通配符的数组的 PowerShellWhere 子句。这是我更大的代码中的命令,
$excludedOUs = @("*OU=Loaners,*", "*OU=InStock,*", "*OU=Conference Room,*","*OU=Training,*")
Get-ADComputer -SearchBase $targetOU -Property LastLogonDate,LastLogon |
Where-Object { $_.DistinguishedName -notin $excludedOUs } | Select-Object Name,DistinguishedName, @{l='LastLogonDate';e={[DateTime]::FromFileTime($_.LastLogon)}}
我想从 $targetOU 返回计算机列表,但我想从 $targetOU 中排除子 OU 列表。我看过多篇文章解释了为什么失败(“notin”中不允许使用通配符,需要使用 -like 和 -notlike 与通配符等),并且我还看到了使用正则表达式来解决问题的建议问题。不幸的是,我一看到正则表达式总是目光呆滞,永远不知道如何正确使用它们。最终,我希望根本不必在数组中使用通配符。如果 $excludedOUs 数组是,
$excludedOUs = @("Loaners", "InStock", "Conference Room", "Training")
我更喜欢它。但是,我需要使用通配符,因为子 OU 只是 DistinguishedName 属性的一部分。此外,该数组可能并不总是仅限于这四个项目。它可能是单个项目,或者没有,或者数十个。我不知道组织中的其他人将如何使用它。如有任何建议,我们将不胜感激。
正如您所注意到的,
-in
和-contains
及其否定变体仅执行全值、文字相等比较。
不幸的是,
-like
(通配符匹配运算符)和-match
(正则表达式匹配运算符)都不支持模式数组进行匹配,从 PowerShell 7.4 开始:
拥有这种能力(“任何一个”模式匹配被认为是整体匹配)将会很有用; 构造一个singleregex,它使用alternation(|
),您可以与
-match
/-notmatch
一起使用,这很容易以编程方式完成:使用文字子字符串
*
字符,假设-match
/
-notmatch
默认执行子字符串(模式)匹配。 用
|
,表示具有交替的正则表达式,这意味着
任何一个子字符串匹配。 注意:如果文字子字符串恰好包含正则表达式元字符,例如
.
或 +
[regex]::Escape()
.NET 方法对它们进行 转义 - 请参阅下面源代码中的相关注释.
另一种方法是使用 \
执行角色个体转义
-notmatch
# Define the exclusion as literal substrings, without "*"
$excludedOUs =
@("OU=Loaners,", "OU=InStock,", "OU=Conference Room,","OU=Training,")
# Join them with "|", to construct a single regex that matches
# any one of the substrings.
# In cases where the array elements contain regex metacharacters (see above),
# use the following instead:
# $regexExcludedOUs = $excludedOUs.ForEach({ [regex]::Escape($_) }) -join '|'
$regexExcludedOUs = $excludedOUs -join '|'
# Use the regex with -notmatch
Get-ADComputer -SearchBase $targetOU -Property LastLogonDate,LastLogon |
Where-Object { $_.DistinguishedName -notmatch $regexExcludedOUs } |
Select-Object Name,DistinguishedName, @{l='LastLogonDate';e={[DateTime]::FromFileTime($_.LastLogon)}}