PowerShell
Arbeiten mit der PowerShell-Pipeline
Suche…
Einführung
In PowerShell wird ein Objekt-Pipelining-Modell eingeführt, mit dem Sie ganze Objekte durch die Pipeline an verbrauchende Commandlets oder (mindestens) die Ausgabe senden können. Im Gegensatz zum klassischen String-basierten Pipelining müssen Informationen in Pipe-Objekten nicht an bestimmten Positionen sein. Commandlets können erklären, mit Objekten aus der Pipeline als Eingabe zu interagieren, während Rückgabewerte automatisch an die Pipeline gesendet werden.
Syntax
- BEGIN Der erste Block. Einmal am Anfang ausgeführt. Die Pipeline-Eingabe hier ist $ null, da sie nicht festgelegt wurde.
- PROCESS Der zweite Block. Wird für jedes Element der Pipeline ausgeführt. Der Pipeline-Parameter entspricht dem aktuell verarbeiteten Element.
- ENDE Letzter Block. Einmal ausgeführt am Ende. Der Pipeline-Parameter ist gleich dem letzten Element der Eingabe, da er seit der Einstellung nicht geändert wurde.
Bemerkungen
In den meisten Fällen handelt es sich bei der Eingabe der Pipeline um ein Array von Objekten. Obwohl das Verhalten des Blocks PROCESS{}
dem foreach{}
Block ähnelt, erfordert das Überspringen eines Elements im Array einen anderen Prozess.
Wenn Sie, wie in foreach{}
, innerhalb des PROCESS{}
Blocks continue
, würde dies die Pipeline zerstören und alle folgenden Anweisungen einschließlich des END{}
Blocks überspringen. Verwenden Sie stattdessen return
, um den Block PROCESS{}
für das aktuelle Element zu beenden und zum nächsten zu wechseln.
In einigen Fällen müssen die Ergebnisse von Funktionen mit unterschiedlicher Codierung ausgegeben werden. Die Codierung der Ausgabe der CmdLets wird durch die Variable $OutputEncoding
gesteuert. Wenn die Ausgabe für native Anwendungen in einer Pipeline abgelegt werden soll, $OutputEncoding = [Console]::OutputEncoding
es sich, die Kodierung entsprechend dem Ziel $OutputEncoding = [Console]::OutputEncoding
Zusätzliche referenzen:
Blogartikel mit mehr $OutputEncoding
https://blogs.msdn.microsoft.com/powershell/2006/12/11/outputencoding-to-the-rescue/
Schreibfunktionen mit Advanced Lifecycle
Dieses Beispiel zeigt, wie eine Funktion Eingaben mit Pipelines akzeptieren und effizient wiederholen kann.
Beachten Sie , dass die begin
und end
Strukturen der Funktion sind optional , wenn Pipelining, aber das process
ist erforderlich, wenn mit ValueFromPipeline
oder ValueFromPipelineByPropertyName
.
function Write-FromPipeline{
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline)]
$myInput
)
begin {
Write-Verbose -Message "Beginning Write-FromPipeline"
}
process {
Write-Output -InputObject $myInput
}
end {
Write-Verbose -Message "Ending Write-FromPipeline"
}
}
$foo = 'hello','world',1,2,3
$foo | Write-FromPipeline -Verbose
Ausgabe:
VERBOSE: Beginning Write-FromPipeline
hello
world
1
2
3
VERBOSE: Ending Write-FromPipeline
Grundlegende Pipeline-Unterstützung in Funktionen
Dies ist ein Beispiel für eine Funktion mit einer möglichst einfachen Unterstützung für das Pipelining.
Für jede Funktion mit Pipeline-Unterstützung muss mindestens ein Parameter festgelegt sein, für den ParameterAttribute ValueFromPipeline
oder ValueFromPipelineByPropertyName
festgelegt ist (siehe unten).
function Write-FromPipeline {
param(
[Parameter(ValueFromPipeline)] # This sets the ParameterAttribute
[String]$Input
)
Write-Host $Input
}
$foo = 'Hello World!'
$foo | Write-FromPipeline
Ausgabe:
Hello World!
Hinweis: In PowerShell 3.0 und höher werden Standardwerte für ParameterAttributes unterstützt. In früheren Versionen müssen Sie ValueFromPipeline=$true
angeben.
Arbeitskonzept der Pipeline
In einer Pipeline-Reihe verläuft jede Funktion parallel zu den anderen, wie parallele Threads. Das erste bearbeitete Objekt wird zur nächsten Pipeline übertragen und die nächste Bearbeitung wird sofort in einem anderen Thread ausgeführt. Dies erklärt den hohen Geschwindigkeitsgewinn im Vergleich zum Standard ForEach
@( bigFile_1, bigFile_2, ..., bigFile_n) | Copy-File | Encrypt-File | Get-Md5
- Schritt - kopiere die erste Datei (in
Copy-file
Thread) - Schritt - Zweite Datei kopieren (in
Copy-file
Thread) und gleichzeitig ErsteEncrypt-File
(inEncrypt-File
) - Schritt - dritte Datei kopieren (in
Copy-file
Thread) und zweite Datei gleichzeitig verschlüsseln (inEncrypt-File
) und gleichzeitigget-Md5
der ersten (inGet-Md5
)