哈希表内的PowerShell管道脚本块

哈希表内的PowerShell管道脚本块,powershell,Powershell,希望这是一个PowerShell noob问题,但如何访问同样位于哈希表中的脚本块中的当前管道对象 以下是我试图做的全部工作: Get-ADGroupMember "Group Name" | Where {$_.objectClass -eq "user"} | Get-ADUser -properties extensionAttribute1 | Where {$_.extensionAttribute1 -ne ($_.UserPrincipalName -

希望这是一个PowerShell noob问题,但如何访问同样位于哈希表中的脚本块中的当前管道对象

以下是我试图做的全部工作:

Get-ADGroupMember "Group Name" | 
    Where {$_.objectClass -eq "user"} | 
    Get-ADUser -properties extensionAttribute1 | 
    Where {$_.extensionAttribute1 -ne ($_.UserPrincipalName -replace "@ADdomain.com", "@GAdomain.com")} | 
    Set-ADUser -replace @{extensionAttribute1=&{$_.UserPrincipalName -replace "@ADdomain.com", "@GAdomain.com"}}
除了最后一行之外,我的一切都正常工作,新的extensionAttribute1应该从当前用户UserPrincipalName生成,替换域。运行此代码会导致错误:

+ Set-ADUser <<<<  -replace @{ExtensionAttribute1=&{$_.UserPrincipalName -replace "@ADdomain.com", "@GAdomain.com"}}
+ CategoryInfo          : InvalidOperation: (CN=Bar\, Fo...ADdomain,DC=com:ADUser) [Set-ADUser], ADInvalidOperationException
+ FullyQualifiedErrorId : replace,Microsoft.ActiveDirectory.Management.Commands.SetADUser

简短的回答似乎是在您的管道中使用foreach,例如:

Get-ADGroupMember "Group Name" | 
    Where {$_.objectClass -eq "user"} | 
    Get-ADUser -properties extensionAttribute1 | 
    Where {$_.extensionAttribute1 -ne ($_.UserPrincipalName -replace "@ADdomain.com", "@GAdomain.com")} | 
    foreach-objct {Set-ADUser $_ -replace @{extensionAttribute1=&{$_.UserPrincipalName -replace "@ADdomain.com", "@GAdomain.com"}}}
至于原因,我很确定这是因为Set-ADUser只接受一个对象,不管它是一个ADUser还是一个ADUser集合。由于$u表示这一点,因此您使用它的方式使Set ADUser将$u视为您在管道中提供的一个对象—用户组,而不是每个用户

注:以下是猜测!如果我错了,请纠正我

关于设置ADUser获取一个或多个对象。。。这是我的猜测。如果查看的输入类型,它会给出None或Microsoft.ActiveDirectory.Management.ADUser的类型。但是正如您所看到的,您还可以传递ADUser对象的集合,并且Set ADUser也会接受这一点。根据我对该cmdlet的理解,调用该cmdlet时,可以对该集合中的所有对象运行相同的Set命令。例如,假设$users包含管道中的所有内容,您可以按照前面提到的方法执行:

$users | Set-ADUser -replace @{extensionAttribute1=&{"foobar"}}
我的猜测是,在幕后,Set ADUser通过在代码中将设置为true并将您提供的参数应用于其中的每个对象,接受$users作为单个参数值。由于集合的迭代发生在已不在PowerShell中的cmdlet代码中,因此它是已编译的.Net代码,$在这里表示每个对象时没有任何用处


我不确定为什么管道允许您以伪foreach方式运行,因为它们具有相同的输入类型,您可以在不使用foreach的情况下以类似的方式调用它们,但根据证据,我必须假设它是隐藏的。如果有人有进一步的见解,我肯定很想知道。我可能完全偏离了底线

我认为这里发生的事情是Set ADUser一次接受了一批信息,因此类似于调用$myArrayFuser | Set ADUser。。。管道中的单个对象是数组,而不是我猜的每个用户。如果改为用Foreach对象{Set ADUser$u2;-replace@{extensionAttribute1=&{$2;.UserPrincipalName-replace@ADdomain.com,@GAdomain.com}替换最后一行,这行吗?这意味着大量的个人电话,而不是一个大电话,但我认为这应该是可行的。我现在无法测试它,但请告诉我它是否有效。@squid808是的,确实有效。奇怪的是,$只对某些commandlet有效吗?我认为更多的是关于如何使用它,因为它代表一个值,这个值。我会在答案中加入我的思考,这样我可以更详细一些。我认为它起作用的主要原因是您为-Identity添加了位置变量。在本例中,您将其设置为set ADUser$\u。。。。在此之前,没有任何东西指示要设置哪个用户。在某些情况下,在PS 3及更高版本中可能会隐含Foreach,或%。基本上它超载了。代码对流中的每个对象运行一次。我似乎不知道什么时候需要在管道中显式使用%{},所以每当有多个对象出现时,我都会显式使用它。不过,我不确定它是在管道中还是在cmdlet代码本身中暗示的。管道是否假设您想要%作为Get ADUser,或者它只是接受一个集合?我只是假设我需要一行程序上的%{}来编写。由于foreach在只有一个对象的情况下工作,因此它变得一致。我也更喜欢脚本,而不是一行程序,它包含注释、函数和格式,便于阅读。
$users | Set-ADUser -replace @{extensionAttribute1=&{"foobar"}}