PowerShell
Trabajando con la tubería de PowerShell
Buscar..
Introducción
PowerShell presenta un modelo de canalización de objetos, que le permite enviar objetos enteros a través de la tubería para consumir comandos o (al menos) la salida. A diferencia de la canalización clásica basada en cadenas, la información de los objetos canalizados no tiene que estar en posiciones específicas. Los Commandlets pueden declarar que interactúan con los objetos de la canalización como entrada, mientras que los valores de retorno se envían automáticamente a la canalización.
Sintaxis
- COMENZAR El primer bloque. Ejecutado una vez al principio. La entrada de canalización aquí es $ null, ya que no se ha establecido.
- PROCESO El segundo bloque. Ejecutado para cada elemento de la tubería. El parámetro pipeline es igual al elemento procesado actualmente.
- FIN del último bloque. Ejecutado una vez al final. El parámetro de canalización es igual al último elemento de la entrada, porque no se ha cambiado desde que se estableció.
Observaciones
En la mayoría de los casos, la entrada de la tubería será una matriz de objetos. Aunque el comportamiento del bloque PROCESS{}
puede parecer similar al bloque foreach{}
, omitir un elemento de la matriz requiere un proceso diferente.
Si, como en foreach{}
, usó continue
dentro del bloque PROCESS{}
, se rompería la tubería, omitiendo todas las siguientes declaraciones, incluido el bloque END{}
. En su lugar, use return
: solo finalizará el bloque PROCESS{}
para el elemento actual y se moverá al siguiente.
En algunos casos, es necesario generar el resultado de funciones con codificación diferente. La codificación de la salida de los CmdLets está controlada por la variable $OutputEncoding
. Cuando se pretende que la salida se coloque en una tubería hacia aplicaciones nativas, podría ser una buena idea corregir la codificación para que coincida con el destino $OutputEncoding = [Console]::OutputEncoding
Referencias adicionales:
Artículo del blog con más información sobre $OutputEncoding
https://blogs.msdn.microsoft.com/powershell/2006/12/11/outputencoding-to-the-rescue/
Funciones de escritura con ciclo de vida avanzado
Este ejemplo muestra cómo una función puede aceptar entradas canalizadas e iterar de manera eficiente.
Tenga en cuenta que las estructuras de begin
y end
de la función son opcionales cuando se canalizan, pero ese process
es necesario cuando se utiliza 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
Salida:
VERBOSE: Beginning Write-FromPipeline
hello
world
1
2
3
VERBOSE: Ending Write-FromPipeline
Soporte básico de oleoducto en funciones
Este es un ejemplo de una función con el soporte más simple posible para la canalización.
Cualquier función con soporte de canalización debe tener al menos un parámetro con el parámetro ParameterAttribute ValueFromPipeline
o ValueFromPipelineByPropertyName
, como se muestra a continuación.
function Write-FromPipeline {
param(
[Parameter(ValueFromPipeline)] # This sets the ParameterAttribute
[String]$Input
)
Write-Host $Input
}
$foo = 'Hello World!'
$foo | Write-FromPipeline
Salida:
Hello World!
Nota: en PowerShell 3.0 y versiones posteriores, se admiten los valores predeterminados para ParameterAttributes. En versiones anteriores, debe especificar ValueFromPipeline=$true
.
Concepto de trabajo de la tubería
En una serie de tuberías, cada función corre paralela a las demás, como hilos paralelos. El primer objeto procesado se transmite a la siguiente canalización y el siguiente procesamiento se ejecuta inmediatamente en otro hilo. Esto explica la ganancia de alta velocidad en comparación con el estándar ForEach
@( bigFile_1, bigFile_2, ..., bigFile_n) | Copy-File | Encrypt-File | Get-Md5
- paso - copia el primer archivo (en
Copy-file
subproceso delCopy-file
) - paso: copiar el segundo archivo (en
Copy-file
subproceso delCopy-file
) y, simultáneamente, cifrar el primero (enEncrypt-File
) - paso: copiar el tercer archivo (en
Copy-file
subproceso delCopy-file
) y, a la vez, cifrar el segundo archivo (en el archivo deEncrypt-File
) y al mismo tiempoget-Md5
del primero (enGet-Md5
)