嵌套的 Powershell 对象取消引用
Nested Powershell object dereferencing
我目前正在努力完成一项相对简单的任务。
目前我想用 ForEach 对象替换通过 foreach 的迭代,因为我想启用并行化(因为大部分函数纯粹是在等待连接)。
所以
foreach ($vm in $vms)
{
$output = Invoke-AzVMRunCommand -ResourceGroupName $vm.resourceGroup -VMName $vm.name -ScriptPath ".\script.sh" -CommandId RunShellScript -Verbose
...
$result | Add-Member -MemberType NoteProperty "Joins" -Value "$($vm.name.tolower())$($vm.resourceGroup.tolower())$($sub.Id.tolower())"
}
会变成这样:
$vms | ForEach-Object -ThrottleLimit 5 -Parallel {
{
$vm = $_
$output = Invoke-AzVMRunCommand -ResourceGroupName $vm.resourceGroup -VMName $vm.name -ScriptPath ".\script.sh" -CommandId RunShellScript -Verbose
...
$result | Add-Member -MemberType NoteProperty "Joins" -Value "$($vm.name.tolower())$($vm.resourceGroup.tolower())$($sub.Id.tolower())"
}
问题出在最终结果中,因为对此 属性 的嵌套解除引用没有得到正确解析。我强调它取消引用 ForEach 对象而不是指定的 super-class。有人知道如何正确 link 它们吗?
此致
€DIT:
所以既然有人问 $sub 来自哪里,这里有更多细节:
foreach ($sub in $Subscriptions)
{
...
foreach ($vm in $vms)
{
$output = Invoke-AzVMRunCommand -ResourceGroupName $vm.resourceGroup -VMName $vm.name -ScriptPath ".\script.sh" -CommandId RunShellScript -Verbose
...
$result | Add-Member -MemberType NoteProperty "Joins" -Value "$($vm.name.tolower())$($vm.resourceGroup.tolower())$($sub.Id.tolower())"
}
}
Mathias R. Jessen在评论中提供了关键指针:
与 PowerShell 中的后台/线程作业和远程调用一样,包括来自调用方范围的变量值需要使用$using:
scope in ForEach-Object
-Parallel
脚本块.
因为代码中的 $sub
是来自调用者范围的变量(与块局部 $vm
变量相反,后者通过 automatic $_
variable 接收其值,代表 pipeline input手头),你需要将其值引用为$using:sub
.
因此,$($sub.Id.tolower())
必须是 $($using:sub.Id.tolower())
有关何时需要 $using:
及其限制的详细信息,请参阅 。
我目前正在努力完成一项相对简单的任务。
目前我想用 ForEach 对象替换通过 foreach 的迭代,因为我想启用并行化(因为大部分函数纯粹是在等待连接)。
所以
foreach ($vm in $vms)
{
$output = Invoke-AzVMRunCommand -ResourceGroupName $vm.resourceGroup -VMName $vm.name -ScriptPath ".\script.sh" -CommandId RunShellScript -Verbose
...
$result | Add-Member -MemberType NoteProperty "Joins" -Value "$($vm.name.tolower())$($vm.resourceGroup.tolower())$($sub.Id.tolower())"
}
会变成这样:
$vms | ForEach-Object -ThrottleLimit 5 -Parallel {
{
$vm = $_
$output = Invoke-AzVMRunCommand -ResourceGroupName $vm.resourceGroup -VMName $vm.name -ScriptPath ".\script.sh" -CommandId RunShellScript -Verbose
...
$result | Add-Member -MemberType NoteProperty "Joins" -Value "$($vm.name.tolower())$($vm.resourceGroup.tolower())$($sub.Id.tolower())"
}
问题出在最终结果中,因为对此 属性 的嵌套解除引用没有得到正确解析。我强调它取消引用 ForEach 对象而不是指定的 super-class。有人知道如何正确 link 它们吗?
此致
€DIT: 所以既然有人问 $sub 来自哪里,这里有更多细节:
foreach ($sub in $Subscriptions)
{
...
foreach ($vm in $vms)
{
$output = Invoke-AzVMRunCommand -ResourceGroupName $vm.resourceGroup -VMName $vm.name -ScriptPath ".\script.sh" -CommandId RunShellScript -Verbose
...
$result | Add-Member -MemberType NoteProperty "Joins" -Value "$($vm.name.tolower())$($vm.resourceGroup.tolower())$($sub.Id.tolower())"
}
}
Mathias R. Jessen在评论中提供了关键指针:
与 PowerShell 中的后台/线程作业和远程调用一样,包括来自调用方范围的变量值需要使用$using:
scope in ForEach-Object
-Parallel
脚本块.
因为代码中的 $sub
是来自调用者范围的变量(与块局部 $vm
变量相反,后者通过 automatic $_
variable 接收其值,代表 pipeline input手头),你需要将其值引用为$using:sub
.
因此,$($sub.Id.tolower())
必须是 $($using:sub.Id.tolower())
有关何时需要 $using:
及其限制的详细信息,请参阅