代码之家  ›  专栏  ›  技术社区  ›  codewario

如何在active directory cmdlet上有效地使用“-filter”参数?

  •  4
  • codewario  · 技术社区  · 6 年前

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

    Get-ADUser -Filter * | Where-Object { $_.EmailAddress -eq $email }
    

    问题是,您将返回active directory中的每个用户对象,然后再次处理它。我们如何对此进行改进,不仅可以减少运行脚本所需的时间,而且还可以减少不必要的active directory负载,甚至可能减少网络负载?

    1 回复  |  直到 6 年前
        1
  •  8
  •   codewario    6 年前

    有什么不好的 -Filter * 是吗?

    根据您使用的CMDLET,您可以有效地选择和返回AD中存在的每个对象(例如)。 Get-ADUser ,请 Get-ADComputer 我是说, Get-ADGroup ,泛型 Get-ADObject 这是一件昂贵的事情,尤其是在更大的广告环境中。如果您合法地需要对每个可能的对象进行操作,那么这样做是可以的,但是在大多数情况下,您不需要返回所有对象。除此之外,脚本最终处理的数据将远远超过它所需的数据量,从而增加了执行时间,并在不需要时使用了处理时间。

    这个 -Filter 参数可以做的不仅仅是匹配所有内容,这实际上是 -过滤器* 做。这个 Filter string非常像powershell语法(不是很像,但大部分都是这样)。您可以使用与powershell支持的大多数逻辑运算符,它们的工作方式与powershell运算符的工作方式基本相同。这个答案旨在澄清这一点,并解释如何使用这个难以捉摸的参数。这些示例将使用 得到奉承 但这也扩展到了另一个 获取对象 也使用筛选器的Cmdlet。

    句法

    的语法 过滤器 字符串如下: "PropertyName -comparisonoperator 'somevalue'" ,但可以将多个条件与逻辑运算符(如 -and -or 是的。注意regex匹配运算符,比如 -match -notmatch 不工作,但是 -like -notlike 如你所愿工作。

    在属性上匹配

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

    $email = 'box@domain.tld'
    Get-ADUser -Filter "EmailAddress -eq '${email}'"
    

    完成。 得到奉承 将返回emailaddress属性等于 $email 变量是。

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

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

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

    多属性匹配

    对多个属性的匹配并没有太大的不同,但是最好将每个条件括在括号中 () 是的。下面是一个示例,让我们查找非域管理帐户(假设我们通过用户名命名法知道这一点 *-da )没有与之关联的电子邮件地址。

    Get-ADUser -Filter "(samaccountname -notlike '*-da') -and (EmailAddress -notlike '*')"
    

    这个有点棘手,因为在 -过滤器 ,就像 EmailAddress 是的。但是“*”匹配任何非空值,因此我们可以利用 -不像 用于查找空值的比较运算符 电子邮件地址 是的。若要分解筛选器,请确保所有以 -da 与过滤器不匹配, 然后 也只匹配没有 电子邮件地址 价值。

    要避免的事情

    1. Don't try to use a { ScriptBlock } for your filter parameters 是的。是的,我们更愿意写 ScriptBlock 而不是担心 string 并确保它能正常逃脱。使用它们肯定有吸引力。我见过很多答案 脚本块 作为一个 -过滤器 争论,或者有问题的人(包括我自己)试图做这样的事情,然后惊喜!!!不返回任何内容:

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

      -过滤器 不支持 ScriptBlocks ,但他们 有时是一种工作™ 因为他们在被评估之前就已经开始了。如果你使用简单的变量展开 $_ $emailAddress ,但它最终会让您头疼,特别是如果您试图访问对象属性(如上文所述),因为它根本无法工作。每次都使用字符串筛选器,如果需要将对象属性用作筛选器参数,请使用 Variable Substitution Command Substitution 是的。

    2. 不需要指定其他 -Properties 如果你只关心一个属性来过滤它。AD cmdlet可以计算 过滤器 参数,而不需要将它们传递到管道中。

    3. 当我在做的时候,不要用 -Properties * ,除非您出于某种原因正在检查返回对象上的所有属性。仅指定返回AD对象后需要处理的属性。这是有原因的——有些房产的价格特别昂贵。最佳实践是只转发需要在管道中处理的属性。与这个问题有点无关,但仍然需要记住一个非常重要的细节。

    总结

    这些技术使用 -过滤器 在大型AD环境中迭代时,使用AD Cmdlet的参数将节省昂贵的处理时间,并应提高Powershell AD操作的性能。我希望这有助于解释广告cmdlet的一些难以捉摸的行为 -过滤器 参数。