Короткий вопрос: у кого-нибудь есть подробная информация о параметре -RemainingScripts в ForEach-Object?
Длинный вопрос:
Я только начал изучать PowerShell на прошлой неделе и просматриваю все командлеты, чтобы узнать больше. Основываясь на общедоступной документации, мы знаем, что 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"}
Ожидаемый результат: 1 раз для «block1» и «block3», «block2» повторяется для каждого переданного элемента, и счетчик каталогов / файлов все правильно. Все идет нормально.
Что интересно, следующая команда также работает и дает точно такой же результат:
Get-ChildItem | foreach { "block1"
$fileCount = $directoryCount = 0}{ "block2";
if ($_.PsIsContainer) {$directoryCount++} else {$fileCount++}}{
"block3"; "$directoryCount directories and $fileCount files"}
В foreach передано всего 3 ScriptBlocks. Согласно руководству, первый идет в -Process (позиция 1). А как насчет оставшихся 2? Согласно инструкции, параметра с «Позицией 2» нет. Итак, я обратился к Trace-Command и обнаружил, что последние 2 блока скрипта были фактически для RemainingScripts как «IList с 2 элементами».
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 блока, хотя первый переходит в -Process, позже он фактически используется как «Начало», а оставшиеся 2 становятся «Процессом» и «Конец».
Тем не менее, все вышеперечисленное - мое безумное предположение. Я не нашел документации, подтверждающей мое предположение
Итак, наконец, мы возвращаемся к моему короткому вопросу :) У кого-нибудь есть подробная информация о параметре -RemainingScripts в ForEach-Object?
Спасибо.