如何在Active Directory cmdlet上有效使用`-Filter`参数?

Ben*_*est 4 powershell active-directory

我经常在此站点上看到以下类型的代码,特定于AD cmdlet:

Get-ADUser -Filter * | Where-Object { $_.EmailAddress -eq $email }
Run Code Online (Sandbox Code Playgroud)

问题是您要返回Active Directory中的每个用户对象,然后再次处理它.我们如何才能改进这一点,不仅可以减少运行脚本所需的时间,还可以减少Active Directory和网络的不必要负担?

Ben*_*est 8

有什么不好的-Filter *

您有效地选择和返回,存在于AD中的每个对象,根据您所使用的小命令(例如Get-ADUser,Get-ADComputer,Get-ADGroup,通用Get-ADObject等) -这是一个昂贵的事情,特别是在较大的广告环境.如果您合法地需要对每个可能的对象进行操作,那么这样做很好,但在大多数情况下,您不需要返回所有内容.最重要的是,您的脚本最终将处理的数据远远超过其需要的数量,从而增加执行时间并在不需要时使用处理时间.

-Filter参数可以做的不仅仅是匹配所有内容,这实际上是-Filter *做什么的.该Filter字符串非常类似于Powershell语法(不完全,但大部分都在那里).您可以使用Powershell支持的大多数相同的逻辑运算符,它们的工作方式与Powershell运算符的工作方式相同.这个答案旨在澄清这一点,并解释如何使用这个难以捉摸的参数.这些示例将使用Get-ADUsercmdlet,但这也会扩展到Get-ADObject使用过滤器的其他cmdlet.

句法

Filter字符串的语法如下:"PropertyName -comparisonoperator 'somevalue'"尽管您可以将多个条件与逻辑运算符(如-and和)一起使用-or.请注意,正则表达式匹配运营商一样,-match-notmatch不工作,而是-like-notlike工作如你所愿.

匹配房产

要使用问题中的示例,让我们找到一个匹配电子邮件地址的用户,但没有管道Where-Object(疯狂吧???):

$email = 'box@domain.tld'
Get-ADUser -Filter "EmailAddress -eq '${email}'"
Run Code Online (Sandbox Code Playgroud)

完成.Get-ADUser将返回EmailAddress属性等于$email变量的任何帐户.

如果我们想要查找过去30天内未登录的所有用户帐户,该怎么办?但是日期字符串比电子邮件更复杂!谁在乎,还是很简单!

# Get the date from 30 days ago
$notUsedSince = ( Get-Date ).AddDays( -30 )
Get-ADUser -Filter "LastLogonDate -lt '${notUsedSince}'"
Run Code Online (Sandbox Code Playgroud)

这将返回过去30天内未登录的所有用户.

匹配多个属性

匹配多个属性没有太大区别,但最好将每个条件包装在括号中().这是一个例子,让我们找到*-da没有与之关联的电子邮件地址的非域管理员帐户(假设我们通过用户名命名称知道).

Get-ADUser -Filter "(samaccountname -notlike '*-da') -and (EmailAddress -notlike '*')"
Run Code Online (Sandbox Code Playgroud)

这个有点棘手,因为我们不能传入一个空值来表示条件的右侧-Filter,就像在这种情况下一样EmailAddress.但是'*'匹配任何非空值,因此我们可以利用-notlike比较运算符来利用该行为来查找空值EmailAddress.要细分过滤器,请确保过滤器-da不匹配任何结尾的帐户,然后只匹配没有EmailAddress值的帐户.

要避免的事情

  1. 不要尝试使用a { ScriptBlock }作为过滤器参数.是的,我们更乐于编写一个而ScriptBlock不是担心建立一个string并确保它正确地逃脱.使用它们绝对有吸引力.我见过用这么多的答案ScriptBlock作为-Filter参数,或者有问题(包括我自己)试图做这样的事情,并让人大跌眼镜!什么都没有返回:

    Import-Csv C:\userInfoWithEmails.csv | Foreach-Object { Get-ADUser -Filter { EmailAddress -eq $_.Email } }

    -Filter不支持ScriptBlocks,但他们有点工作,因为他们在评估之前得到了ToString'd.他们将在技术上工作,如果你使用简单的变量扩展类似$_$emailAddress,但最终会导致你头疼,尤其是当您尝试访问对象属性(如上面),因为它是行不通的.每次都使用字符串过滤器,如果需要使用对象属性作为过滤器参数,请使用" 变量替换"或" 命令替换".

  2. -Properties如果您只关心要对其进行过滤的属性,则无需指定其他内容.AD cmdlet可以评估Filter参数中的所有属性,而无需将它们传递给管道.

  3. 虽然我在这里,但是不要使用-Properties *,除非你因某种原因检查返回物体上的所有属性.仅指定在返回AD对象后需要处理的属性.这是有原因的 - 获取值的某些属性特别昂贵.最佳做法是仅转发处理管道所需的属性.与这个问题有点无关,但仍然是一个非常重要的细节.

总结

-Filter参数与AD cmdlet一起使用时,这些技术可以在迭代大型AD环境时节省昂贵的处理时间,并且可以提高Powershell AD操作的性能.我希望这有助于解释AD cmdlet -Filter参数的一些难以捉摸的行为.


归档时间:

查看次数:

551 次

最近记录:

7 年,10 月 前