我最近写了这个答案并偶然发现了一些有趣的东西。
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")}
...方法
- “找出描述属性等于文本字符串“auto”。要使此比较有效,字符串需要存在于描述字段中,以便
-eq
操作员能够将其与“auto”进行比较。由于无法将 NULL 与字符串值进行比较,因此会从此比较中删除 NULL 值。 - 独立于
-eq
过滤参数给我不是 的结果的所有内容(description -eq "auto")
,这将包括 NULL,因为原始 cmdletget-aduser
包括所有 AD 用户。它不必使用运算符将任何内容与其他内容进行比较-not
。它只是为您提供了除过滤器结果之外的所有内容(description -eq "auto")
。
在您的示例中,假设您有 1 个 AD 用户,其描述等于“auto”,数百个用户的描述不是“auto”,数百个用户的描述为 NULL。单步执行命令逻辑将执行:
- 给我所有描述等于“auto”的 AD 用户 (get-aduser) - 结果为 1 个用户
- 给我所有不是您刚刚给我的 AD 用户 - 结果是几百个包含其他内容的用户和几百个包含 NULL 的用户。
由于它不必使用运算符将任何内容与其他任何内容进行比较-not
,因此结果包括在原始get-aduser
cmdlet 中捕获的 NULL 描述用户。
第二条命令:
{description -ne "auto"}
...方法
- “找出描述属性不相等精确的字符串“auto”。同样,要使此比较有效,字符串需要存在于描述字段中,以便
-ne
运算符能够将其与“auto”进行比较。由于无法将 NULL 与字符串值进行比较,因此此比较会删除 NULL 值。
在您的示例中,再次假设您有 1 个 AD 用户,其描述等于“auto”,数百个用户的描述不是“auto”,数百个用户的描述为 NULL。单步执行命令逻辑将执行以下操作:
- 给我所有描述不等于“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))'