PowerShell
Lavorare con la pipeline di PowerShell
Ricerca…
introduzione
PowerShell introduce un modello di pipeline degli oggetti, che consente di inviare interi oggetti attraverso la pipeline al consumo di commandlet o (almeno) all'output. A differenza del pipelining basato su stringhe classiche, non è necessario che le informazioni negli oggetti collegati siano su posizioni specifiche. I Commandlet possono dichiarare di interagire con Oggetti dalla pipeline come input, mentre i valori di ritorno vengono inviati automaticamente alla pipeline.
Sintassi
- INIZIA Il primo blocco. Eseguito una volta all'inizio. L'input della pipeline qui è $ null, poiché non è stato impostato.
- PROCESSO Il secondo blocco. Eseguito per ciascun elemento della pipeline. Il parametro pipeline è uguale all'elemento attualmente elaborato.
- FINE Ultimo blocco. Eseguito una volta alla fine. Il parametro pipeline è uguale all'ultimo elemento dell'input, poiché non è stato modificato da quando è stato impostato.
Osservazioni
Nella maggior parte dei casi, l'input della pipeline sarà una serie di oggetti. Sebbene il comportamento del blocco PROCESS{}
possa sembrare simile al blocco foreach{}
, saltare un elemento nell'array richiede un processo diverso.
Se, come in foreach{}
, hai usato continue
nel blocco PROCESS{}
, interromperà la pipeline, saltando tutte le seguenti istruzioni incluso il blocco END{}
. Invece, usa return
- termina solo il blocco PROCESS{}
per l'elemento corrente e passa al successivo.
In alcuni casi, è necessario produrre il risultato di funzioni con codifica diversa. La codifica dell'output di CmdLets è controllata dalla variabile $OutputEncoding
. Quando l'output è destinato a essere inserito in una pipeline per le applicazioni native, potrebbe essere una buona idea correggere la codifica in modo che corrisponda alla destinazione $OutputEncoding = [Console]::OutputEncoding
Ulteriori riferimenti:
Articolo del blog con più informazioni su $OutputEncoding
https://blogs.msdn.microsoft.com/powershell/2006/12/11/outputencoding-to-the-rescue/
Funzioni di scrittura con ciclo di vita avanzato
Questo esempio mostra come una funzione può accettare input pipeline e iterare in modo efficiente.
Si noti che le begin
e end
strutture della funzione sono facoltativi quando pipelining, ma che process
è necessaria quando si utilizza ValueFromPipeline
o 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
Produzione:
VERBOSE: Beginning Write-FromPipeline
hello
world
1
2
3
VERBOSE: Ending Write-FromPipeline
Supporto per pipeline di base in funzioni
Questo è un esempio di una funzione con il supporto più semplice possibile per il pipelining.
Qualsiasi funzione con supporto pipeline deve avere almeno un parametro con ParameterAttribute ValueFromPipeline
o ValueFromPipelineByPropertyName
impostato, come illustrato di seguito.
function Write-FromPipeline {
param(
[Parameter(ValueFromPipeline)] # This sets the ParameterAttribute
[String]$Input
)
Write-Host $Input
}
$foo = 'Hello World!'
$foo | Write-FromPipeline
Produzione:
Hello World!
Nota: in PowerShell 3.0 e versioni successive, è supportato Valori predefiniti per ParameterAttributes. Nelle versioni precedenti, è necessario specificare ValueFromPipeline=$true
.
Concetto di lavoro della pipeline
In una serie di condotte ciascuna funzione viene eseguita parallelamente alle altre, come i thread paralleli. Il primo oggetto elaborato viene trasmesso alla pipeline successiva e l'elaborazione successiva viene immediatamente eseguita in un altro thread. Questo spiega il guadagno ad alta velocità rispetto allo standard ForEach
@( bigFile_1, bigFile_2, ..., bigFile_n) | Copy-File | Encrypt-File | Get-Md5
- passo - copia il primo file (in Thread
Copy-file
) - passo - copia il secondo file (in Thread
Copy-file
) e contemporaneamente Cripta il primo (inEncrypt-File
) - step - copia il terzo file (in Thread del
Copy-file
) e simultaneamente cripta il secondo file (inEncrypt-File
) e contemporaneamenteget-Md5
del primo (inGet-Md5
)