PowerShell
Werken met de PowerShell-pijplijn
Zoeken…
Invoering
PowerShell introduceert een objectpijplijnmodel, waarmee u hele objecten via de pijplijn naar verbruikende commandlets of (tenminste) de uitvoer kunt sturen. In tegenstelling tot klassieke string-gebaseerde pipelining hoeft informatie in piped objecten niet op specifieke posities te staan. Commandlets kunnen verklaren om te communiceren met objecten uit de pijplijn als invoer, terwijl retourwaarden automatisch naar de pijplijn worden verzonden.
Syntaxis
- BEGIN Het eerste blok. In het begin één keer uitgevoerd. De pijplijninvoer hier is $ null, omdat deze niet is ingesteld.
- PROCES Het tweede blok. Uitgevoerd voor elk element van de pijplijn. De pijplijnparameter is gelijk aan het momenteel verwerkte element.
- END Laatste blok. Aan het einde eenmaal uitgevoerd. De pijplijnparameter is gelijk aan het laatste element van de invoer, omdat deze niet is gewijzigd sinds deze is ingesteld.
Opmerkingen
In de meeste gevallen zal de invoer van de pijplijn een reeks objecten zijn. Hoewel het gedrag van het PROCESS{}
-blok lijkt op het foreach{}
-blok, vereist het overslaan van een element in de array een ander proces.
Als u, zoals in foreach{}
, continue
binnen het PROCESS{}
-blok, zou dit de pijplijn onderbreken en alle volgende verklaringen overslaan, inclusief het END{}
-blok. Gebruik in plaats daarvan return
- het beëindigt alleen het PROCESS{}
-blok voor het huidige element en gaat naar het volgende.
In sommige gevallen moet het resultaat van functies met verschillende codering worden uitgevoerd. De codering van de uitvoer van de CmdLets wordt bestuurd door de variabele $OutputEncoding
. Wanneer de uitvoer in een pijplijn naar native toepassingen moet worden geplaatst, is het misschien een goed idee om de codering te corrigeren zodat deze overeenkomt met het doel $OutputEncoding = [Console]::OutputEncoding
Aanvullende referenties:
Blogartikel met meer inzicht over $OutputEncoding
https://blogs.msdn.microsoft.com/powershell/2006/12/11/outputencoding-to-the-rescue/
Schrijffuncties met geavanceerde levenscyclus
Dit voorbeeld laat zien hoe een functie pijplijninvoer kan accepteren en efficiënt kan itereren.
Merk op dat het begin
en end
structuren van de functie zijn optioneel als een pijplijn, maar dat process
is vereist wanneer ValueFromPipeline
of 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
Output:
VERBOSE: Beginning Write-FromPipeline
hello
world
1
2
3
VERBOSE: Ending Write-FromPipeline
Elementaire pijplijnondersteuning in functies
Dit is een voorbeeld van een functie met de eenvoudigst mogelijke ondersteuning voor pipelining.
Elke functie met pijplijnondersteuning moet ten minste één parameter hebben met de parameter ParameterAttribute ValueFromPipeline
of ValueFromPipelineByPropertyName
, zoals hieronder wordt weergegeven.
function Write-FromPipeline {
param(
[Parameter(ValueFromPipeline)] # This sets the ParameterAttribute
[String]$Input
)
Write-Host $Input
}
$foo = 'Hello World!'
$foo | Write-FromPipeline
Output:
Hello World!
Opmerking: in PowerShell 3.0 en hoger worden standaardwaarden voor ParameterAttributes ondersteund. In eerdere versies moet u ValueFromPipeline=$true
opgeven.
Werkconcept pijpleiding
In een pijplijnreeks loopt elke functie parallel aan de andere, zoals parallelle threads. Het eerste verwerkte object wordt overgedragen naar de volgende pijplijn en de volgende verwerking wordt onmiddellijk uitgevoerd in een andere thread. Dit verklaart de hoge snelheidstoename vergeleken met de standaard ForEach
@( bigFile_1, bigFile_2, ..., bigFile_n) | Copy-File | Encrypt-File | Get-Md5
- stap - kopieer het eerste bestand (in
Copy-file
Thread) - stap - kopieer het tweede bestand (in
Copy-file
Thread) en codeer tegelijkertijd het eerste (inEncrypt-File
) - stap - kopieer het derde bestand (in
Copy-file
Thread) enget-Md5
tegelijkertijd het tweede bestand (inEncrypt-File
) enget-Md5
tegelijkertijdget-Md5
van de eerste (inGet-Md5
)