PowerShell 中的这个 AD 过滤器到底是怎么回事?

PowerShell 中的这个 AD 过滤器到底是怎么回事?

最近写了这个答案并偶然发现了一些有趣的东西。

get-aduser -filter {-not (description -eq "auto")} | measure-object

get-aduser -filter {description -ne "auto"} | measure-object

针对相同数据运行时,会返回两个截然不同的结果,第一个命令返回预期值。乍一看,描述字段中为空值的用户似乎不是在第二个命令中返回匹配项,即使 NULL 显然不等于“auto”。

聊天室里有几个人看到了这个,证实我没有疯。这是怎么回事?

答案1

两者之间的主要区别在于,第一个命令不涉及直接比较值以获取所有结果,而第二个命令则涉及。第一个命令包含 NULL 结果,而第二个命令不包含(正如 MDMarra 已经发现的那样)。两个命令都以这个 cmdlet 开头:

get-aduser

在执行下列操作时,请记住此 cmdlet 的结果包括所有 AD 用户,而不管-filter其后的参数中的其他内容。

现在让我们来分析一下两个不同的部分。第一个:

{-not (description -eq "auto")}

...方法

  1. “找出描述属性等于文本字符串“auto”。要使此比较有效,字符串需要存在于描述字段中,以便-eq操作员能够将其与“auto”进行比较。由于无法将 NULL 与字符串值进行比较,因此会从此比较中删除 NULL 值。
  2. 独立于-eq过滤参数给我不是 的结果的所有内容(description -eq "auto"),这将包括 NULL,因为原始 cmdletget-aduser包括所有 AD 用户。它不必使用运算符将​​任何内容与其他内容进行比较-not。它只是为您提供了除过滤器结果之外的所有内容(description -eq "auto")

在您的示例中,假设您有 1 个 AD 用户,其描述等于“auto”,数百个用户的描述不是“auto”,数百个用户的描述为 NULL。单步执行命令逻辑将执行:

  1. 给我所有描述等于“auto”的 AD 用户 (get-aduser) - 结果为 1 个用户
  2. 给我所有不是您刚刚给我的 AD 用户 - 结果是几百个包含其他内容的用户和几百个包含 NULL 的用户。

由于它不必使用运算符将​​任何内容与其他任何内容进行比较-not,因此结果包括在原始get-adusercmdlet 中捕获的 NULL 描述用户。

第二条命令:

{description -ne "auto"}

...方法

  1. “找出描述属性不相等精确的字符串“auto”。同样,要使此比较有效,字符串需要存在于描述字段中,以便-ne运算符能够将其与“auto”进行比较。由于无法将 NULL 与字符串值进行比较,因此此比较会删除 NULL 值。

在您的示例中,再次假设您有 1 个 AD 用户,其描述等于“auto”,数百个用户的描述不是“auto”,数百个用户的描述为 NULL。单步执行命令逻辑将执行以下操作:

  1. 给我所有描述不等于“auto”的 AD 用户 - 结果是几百个描述中除“auto”之外的用户。它不会提取具有 NULL 描述的用户,因为它无法将 NULL 与文本字符串进行比较。

无论如何,这两个命令之间的整个差异绝对是非直观的。

使用此命令您应该能够捕获其中带有“-and”的 NULL,如下所示:

{description -ne "auto" -and description -ne $NULL}

由于现在无法测试语法,因此我对语法还不是 100%,而且可能还有比这更好的方法。当它全部分解时,它相当平淡无奇,需要大量输入才能解释清楚,但在使用各种运算符之前,我遇到过类似的奇怪东西,并且进行了大量的反复试验,因为我永远记不住使用每个运算符时的所有注意事项。

参考:http://technet.microsoft.com/en-us/library/hh847732.aspx

比较运算符

使用比较运算符(-eq、-ne、-gt、-lt、-le、-ge)来比较值和测试条件。例如,您可以比较两个字符串值来确定它们是否相等。

比较运算符包括匹配运算符(-match、-notmatch),使用正则表达式查找模式;替换运算符(-replace),使用正则表达式更改输入值;类似运算符(-like、-notlike),使用通配符(*)查找模式;包含运算符(in、-notin、-contains、-notcontains),确定测试值是否出现在参考集中。

它们还包括按位运算符(-bAND、-bOR、-bXOR、-bNOT)来操作值中的位模式。

有关详细信息,请参阅 about_Comparison_Operators

逻辑运算符

使用逻辑运算符(-and、-or、-xor、-not、!)将条件语句连接成一个复杂的条件语句。例如,您可以使用逻辑 -and 运算符来创建具有两个不同条件的对象过滤器。

有关详细信息,请参阅 about_Logical_Operators。

答案2

在搜索时出现这个老问题,现在添加它:

使用 -Filter 进行否定匹配(例如 -ne 或 -notlike)可排除具有空值的结果。要包含这些结果,您还需要使用以下方法进行明确匹配-不喜欢 '*'作为-eq ''-eq $NULL不是有效的过滤器。请注意,这是 -Filter 的一个怪癖,使用直接 -LdapFilter 确实会否定匹配空值。

下面是 Filter 和 LdapFilter 带有否定的多重匹配示例:

Get-ADUser -Filter { mail -like '*example*' -and (description -ne 'example' -or description -notlike '*') }

Get-ADUser -LdapFilter '(&(mail=*example*)(!description=example))'

相关内容