我正在管道中运行一系列cmdlet,为每个cmdlet设置-PipeLineVariable,但由于在管道中使用了更高级别的Sort-Object cmdlet,我得到了意外的结果。
例如,以示例代码为例,它只是我完整代码的一部分。Get-VMhost是随机抽取主机,但我的OCD想要一个按字母顺序排列的列表,只想选择前两个。因此,我在Get-VMhost之后添加了一个排序对象,但这在最后破坏了管道变量。
get-vmhost -PipelineVariable VMHost | sort Name | select -first 2 | % {write-host $vmhost}
VMHost3
VMHost3
相反,我希望看到
VMHost1
VMHost2
我理解这是一些cmdlet(如Sort Object(必须聚合所有输入以进行处理,然后中断流的结果。我有点理解这一点。
不使用。。。
Select -First 2
我会得到整个数据集,我可以简单地进行排序,作为对所有数据集进行排序的最后一步。我也可以在末尾添加select-first 2。我只是想了解这个问题,为什么会发生,以及是否有一个内联的解决方案。
***编辑。。。我有我的答案,那就是简单地在sort语句中设置管道变量。感谢@mktlement0
您只需在Sort-Object
cmdlet中使用公共-PipelineVariable
参数而不是Get-VMHost
,即可使管道变量反映排序的对象序列。
一个简化的例子:
3, 6, 2, 1 | Sort-Object -PipelineVariable value | Select-Object -First 2 |
ForEach-Object { $value }
输出:
1
2
问题中的代码的行为符合预期/设计(见下文(。
我不确定你想要实现什么,但可能你想要以下内容:
$myVMs = get-vmhost | sort Name | select -first 2
$myVMs | ForEach-Object { write-host $_ }
或者,在单个管道中:
get-vmhost | sort Name | select -first 2 | ForEach-Object { write-host $_ }
参考:about_CommonParameters
PipelineVariable允许访问使用此参数的命令传递到下一个管道段的最新值。管道中的任何命令都可以使用命名的PipelineVariable访问该值。当变量传递到下一个管线段时,会将该值分配给该变量。这使得PipelineVariable比可能需要在多个位置分配的特定临时变量更易于使用。
与
$_
或$PSItem
不同,使用PipelineVariable允许任何管道命令访问由上一个命令以外的命令传递(和保存(的管道值。管道命令可以在处理通过管道的下一个项目时访问管道中的最后一个值。这允许命令将其输出反馈到上一个命令(或其本身(。
注意
PipelineVariable的作用域是在其中调用它的管道。管道外使用相同名称的变量在执行管道之前会被删除。管道终止时,PipelineVariable超出范围。如果管道中的多个命令指定相同的PipelineVariable,则只有一个共享变量。该变量将使用指定变量的命令的最新管道输出进行更新。
一些阻塞命令在生成任何输出之前收集所有管道项,例如Sort Object或Select Object-Last。在阻塞命令之前的命令中指定的任何PipelineVariable,在阻塞命令之后的命令中使用时,始终包含前一个命令的最终管道项。