简短的问题:有人有关于 ForEach-Object 的 -RemainingScripts 参数的详细信息吗?
长问题:
我从上周刚开始学习 PowerShell,我正在浏览每个 Cmdlet 以了解更多详细信息。根据公开文档,我们知道 ForEach-Object 可以有 Begin-Process-End 块,如下所示:
Get-ChildItem | foreach -Begin { "block1";
$fileCount = $directoryCount = 0} -Process { "block2";
if ($_.PsIsContainer) {$directoryCount++} else {$fileCount++}} -End {
"block3"; "$directoryCount directories and $fileCount files"}
预期结果:“block1”和“block3”1次,“block2”对每个传入的项目重复,目录计数/文件计数都正确。到目前为止,一切都很好。
现在,有趣的是,以下命令也可以工作并给出完全相同的结果:
Get-ChildItem | foreach { "block1"
$fileCount = $directoryCount = 0}{ "block2";
if ($_.PsIsContainer) {$directoryCount++} else {$fileCount++}}{
"block3"; "$directoryCount directories and $fileCount files"}
只有 3 个 ScriptBlocks 传递给 foreach。根据手册,第一个进入 -Process(位置 1)。但是剩下的2个呢?根据手册,没有“位置2”的参数。所以我转向 Trace-Command,发现后面的 2 个脚本块实际上是 RemainingScripts 为“IList with 2 elements”。
BIND arg [$fileCount = $directoryCount = 0] to parameter [Process]
BIND arg [System.Management.Automation.ScriptBlock[]] to param [Process] SUCCESSFUL
BIND arg [System.Collections.ArrayList] to parameter [RemainingScripts]
BIND arg [System.Management.Automation.ScriptBlock[]] to param [RemainingScripts] SUCCESSFUL
因此,如果我将命令更改为:
# No difference with/without the comma "," between the last 2 blocks
Get-ChildItem | foreach -Process { "block1"
$fileCount = $directoryCount = 0} -RemainingScripts { "block2";
if ($_.PsIsContainer) {$directoryCount++} else {$fileCount++}},{
"block3"; "$directoryCount directories and $fileCount files"}
仍然,完全相同的结果。
正如您所注意到的,所有 3 个命令都给出了相同的结果。这提出了一个有趣的问题:后面的两个命令(隐式)都指定了 -Process,但是ForEach-Object 令人惊讶地最终使用 -Process 的参数作为“-Begin”!(脚本块在开始时执行一次)。
该实验表明:
- -RemainingScripts 参数将采用所有未绑定的 ScriptBlocks
- 当传入3个block时,虽然第一个进入-Process,但后来它实际上被用作“Begin”,而剩下的2个成为“Process”和“End”
尽管如此,以上只是我的猜测。我没有找到支持我猜测的文档
所以,最后我们回到我的简短问题 :) 有人有关于 ForEach-Object 的 -RemainingScripts 参数的详细信息吗?
谢谢。