在PowerShell中使用此AD筛选器到底发生了什么?


9

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

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

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

当对相同数据运行时,返回两个截然不同的东西,第一个命令返回期望值。乍一看,即使NULL明显不等于“ auto”,在第二条命令中也不会将在description字段中具有空值的用户作为匹配项返回。

聊天中的几个人对此进行了研究,并证明我没有疯。这里发生了什么?


1
有趣的是,通过管道将其通过Where-object并应用上面无效的过滤器。get-aduser -filter *-属性说明| ?{$ _。description -ne“ Auto”} | 措施
Mike

@Mike是的,这似乎是行为-ne比较运算符-Filter唯一的块。具体地说,当比较的输入值为时$null
jscott 2013年

1
喜欢和不喜欢似乎工作类似。{description -notlike“ something”}无效,但{-not(description -like“ something”)}则无效。可行的方法也需要花费更长的时间进行评估。就像坏了的一样,它并没有评估所有应该评估的对象。
Mike

@Mike是的。实际上,我-notlike本来是偶然发现此方法的,但是-ne当我意识到自己没有得到想要的东西后,便转而使用。TBH,我忘了我什至没有尝试过,直到您提到它为止-但我也可以复制它。
MDMarra

2
只是一个想法,但也许PoSH的-eq/ -ne子句试图表现得像SQL =/ <>?在SQL,foo = NULL并且foo <> NULL将始终返回false,因为NULL是“无与伦比” -只有foo IS NULLfoo IS NOT NULL特种作业会工作。该行为必须是豪华,类似在您的-not (foo -eq "bar")过滤器将返回其一切(foo -eq "bar")回来$false,这foo -eq $null会怎么做。相反,if (!foo -or foo -ne "bar")(等效SQL foo IS NULL OR foo <> 'bar')如何?
jimbobmcgee

Answers:


4

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

get-aduser

进行下面的操作时,请记住,此cmdlet的结果包括所有AD用户,无论其-filter后面的参数中有任何其他内容。

现在,让我们分解两个不同的部分。第一个:

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

...手段

  1. “找出描述属性等于文本字符串“ auto”的位置。要进行此比较,需要在描述字段中存在一个字符串,-eq操作员才能将其与“ auto”进行比较。从中删除NULL值比较,因为它无法将NULL与字符串值进行比较。
  2. 独立于 -eqfilter参数为我提供的不是的所有结果(description -eq "auto"),它将包含NULL,因为原始cmdlet get-aduser包括所有AD用户。它不需要与-not操作员进行任何其他比较。除了(description -eq "auto")过滤器的结果之外,它还为您提供了所有其他功能。

在您的示例中,假设您有1个AD用户,其描述等于“ auto”,几百个带有“ auto”以外的内容,另外几百个带有NULL描述。逐步执行命令逻辑将执行以下操作:

  1. 给我所有描述等于“自动”的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. 给我所有描述不等于“自动”的AD用户-导致数百个用户的描述中包含“自动”以外的内容。它不会将用户使用NULL描述,因为它无法将NULL与文本字符串进行比较。

无论哪种方式,两个命令之间的整体差异绝对是不直观的。

使用此命令,您应该也可以在其中带有“-”的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),使用通配符(*)查找模式;以及包含运算符(位于-notin,-contains,-notcontains中),它们确定测试值是否出现在参考集中。

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

有关更多信息,请参见about_Comparison_Operators

逻辑运算符

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

有关更多信息,请参见about_Logical_Operators。


肯定有很好的概述,但是为什么-ne和-notlike运算符会排除空值?那才是真正的头上划痕。我想知道其设计是否具有一些深奥的.net规范说明,或者它是否存在错误或意外行为?
MDMarra

等待,请仔细阅读。看起来它们只比较字符串,而null属性实际上是null,而不是空字符串。如果不直观,很有趣。
MDMarra

0

搜索时添加到这个老问题:

将-Filter与否定匹配(例如-ne或-notlike)一起使用会排除具有空null值的结果。为了将它们包括在内,您还需要使用-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))'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.