Kurze Frage: hat jemand detaillierte Informationen zu -RemainingScripts Parameter von ForEach-Object?PowerShell: der mysteriöse -RemainingScripts-Parameter von ForEach-Objekt
Lange Frage:
Ich habe gerade angefangen Powershell aus der vergangenen Woche zu lernen und ich bin durch die einzelnen Cmdlets gehen, um mehr Details zu erfahren. Basierend auf öffentliche Dokumentation, wissen wir ForEach-Object Begin-Prozess-End haben Blöcke, wie folgt aus:
Get-ChildItem | foreach -Begin { "block1";
$fileCount = $directoryCount = 0} -Process { "block2";
if ($_.PsIsContainer) {$directoryCount++} else {$fileCount++}} -End {
"block3"; "$directoryCount directories and $fileCount files"}
Ergebnis erwartet wird: 1 mal für "block1" und "Block3", "block2" wird wiederholt für Jedes übergebene Element und die Anzahl/Dateianzahl ist korrekt. So weit, ist es gut.
Nun, was ist interessant, ist der folgende Befehl funktioniert auch und gibt genau das gleiche Ergebnis:
Get-ChildItem | foreach { "block1"
$fileCount = $directoryCount = 0}{ "block2";
if ($_.PsIsContainer) {$directoryCount++} else {$fileCount++}}{
"block3"; "$directoryCount directories and $fileCount files"}
Nur 3 ScriptBlocks bestanden foreach. Basierend auf dem Handbuch geht der erste zu Prozess (Position 1). Aber wie steht es mit den restlichen 2? Laut Handbuch gibt es keinen Parameter mit "Position 2". Also wandte ich mich Trace-Command zu und stellte fest, dass die späteren 2 Skriptblöcke eigentlich zu RemainingScripts als "IList with 2 elements" gehörten.
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
Also, wenn ich den Befehl dazu ändern:
# 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"}
Dennoch genau das gleiche Ergebnis.
So wie Sie bemerkt haben, geben alle 3 Befehle das gleiche Ergebnis. Dies wirft die interessante Frage auf: Beide der beiden letzten Befehle (implizit) angegeben -Process, jedoch ForEach-Object endet überraschend mit dem Argument von -Process als "-Begin"! (Skriptblock wird einmal am Anfang ausgeführt).
Dieses Experiment legt nahe:
- -RemainingScripts Parameter alle ungebundenen ScriptBlocks nehmen
- Wenn drei Blöcke in geben werden, obwohl die erste, -Prozess geht es später tatsächlich als „Begin“ verwendet wird, während die restlichen 2 werden "Prozess" und "Ende"
Dennoch sind alle oben nur meine wilde Vermutung. Ich habe keine Dokumentation gefunden, die meine Vermutung stützt
So, endlich gehen wir zurück zu meiner kurzen Frage :) Jeder hat detaillierte Informationen zu -RemainingScripts Parameter von ForEach-Object?
Danke.
Dank Andy, haben Sie Punkt 1 beantwortet: "-RemainingScripts Parameter wird alle ungebundenen ScriptBlocks nehmen", aber nicht Punkt # 2 "Wenn 3 Blöcke übergeben werden, obwohl der erste geht zu -Process ... "Das ist eigentlich der Hauptgrund, warum diese Frage gestellt wird. Ich habe mehr Nachforschungen angestellt, und jetzt denke ich, dass ich # Punkt 2 beantworten kann. Trotzdem schätze ich Ihre Antwort und die Technik zur Überprüfung der Parameter. Und tut mir leid, ich habe keine Erlaubnis, für deine Antwort zu stimmen, obwohl es sehr nützlich ist. –