为什么$ PSItem在使用基于括号的-Filter参数时没有按预期运行?

Ben*_*est 5 powershell filter active-directory scriptblock

我正在帮助用户解决这个问题,链接到我的答案:Powershell脚本只使用电子邮件地址从.csv添加用户到A/D组?

最初我按如下方式编写脚本,使用基于括号的过滤器,Get-AdUser如下所示:

Import-CSV "C:\users\Balbahagw\desktop\test1.csv" | 
  Foreach-Object {

    # Here, $_.EmailAddress refused to resolve
    $aduser = Get-ADUser -Filter { EmailAddress -eq $_.EmailAddress }

    if( $aduser ) {
      Write-Output "Adding user $($aduser.SamAccountName) to groupname"
      Add-ADGroupMember -Identity groupname -Members $aduser
    } else {
      Write-Warning "Could not find user in AD with email address $($_.EmailAddress)"
    }
  }
Run Code Online (Sandbox Code Playgroud)

但是,$_.EmailAddress未能填充值.但是,将Get-ADUser过滤器更改为基于字符串的过滤器按预期工作:

$aduser = Get-ADUser -Filter "EmailAddress -eq '$($_.EmailAddress)'"

我遇到的奇怪是什么,为什么?是因为当我使用括号时,它被视为一个新范围而$PSItem不会遵循?

mkl*_*nt0 6

  • -Filter参数通常是字符串参数(验证
    Get-Help Get-AdUser -Parameter Filter)

    • 它们通常接受PowerShell代码 - 过滤器是特定于提供程序的,并且通常具有自己的语法,尽管在AD cmdlet的情况下它恰好与PowerShell 类似.
      此外,他们通常不了解PowerShell 变量(见下文).
  • 因此,当传递脚本块({ ... })时,它将转换为字符串,该字符串将计算其文字内容(开始{和结束之间的所有内容}):

    • { EmailAddress -eq $_.EmailAddress }.ToString()产生文字字符串EmailAddress -eq $_.EmailAddress- 没有任何评估 - 这就是Get-AdUser看到的 - 没有评估发生.

    • 在支持广泛但不明智的将脚本块传递给-FilterAD cmdlet参数的广泛但不明智的做法的大概是善意但误导的努力中,似乎这些cmdlet实际上显式扩展了简单的变量引用,例如$_在它们收到的字符串文字中,但这不适用于表达式,例如访问变量的属性($_.EmailAddress)

因此,-Filter参数通常应作为可扩展的字符串("...")传递 ; 在手头的情况下:

 -Filter  "EmailAddress -eq '$($_.EmailAddress)'"
Run Code Online (Sandbox Code Playgroud)

即,唯一的可靠的解决方案是使用字符串与可变部件烘烤,在前面,通过串扩展,如上所示.

对于既不是数字也不是字符串的值,例如日期,您可能必须使用文字字符串('...')并依赖AD提供程序评估对PowerShell变量的简单引用的能力(例如$date) - 有关详细信息,请参阅我的答案.

如上所述,AD过滤器的语法仅与PowerShell 类似:它仅支持PowerShell支持的运算符的子集,并且支持的运算符在行为上略有不同 - 请参阅Get-Help about_ActiveDirectory_Filter.

  • 这是很有诱惑力使用脚本块,因为里面的代码不需要嵌入报价/无报价字符的交替,并没有使用子表达式运算符的转义$(...).但是,除了使用脚本块作为通常效率低下的字符串之外,这里的问题是脚本块正在做出它无法保留的承诺:看起来你传递了一段PowerShell代码,但你不是 -它只适用于简单的情况(然后只是由于上面提到的错误的住宿); 一般来说,很难记住在什么情况下它不起作用以及如果它失败了如何使其工作.

  • 因此,官方文档在其示例中使用脚本块是非常不幸的.

有关更全面的讨论,请参阅我的这个答案.