Compartir a través de


Limitaciones de las transcripciones de PowerShell

Write-Host Mezclar la salida con los objetos de salida, las cadenas y la transcripción de PowerShell es complicado. Hay una interacción sutil entre el script y cómo funciona la transcripción con canalizaciones de PowerShell que pueden tener resultados inesperados.

Al emitir objetos desde el script, el formato de esos objetos se controla mediante Out-Default. Pero la aplicación de formato puede producirse después de que el script se haya completado y se haya detenido la transcripción. Esto significa que la salida no se transcribe. Las cadenas se manejan de manera diferente. A veces, la cadena de salida se formatea, pero no siempre. Write-Host realiza una escritura inmediata en el proceso de host. Write-Output se envía mediante el sistema de aplicación de formato. La combinación de la salida de objetos complejos con escrituras en el host dificulta la predicción de lo que se registra en la transcripción.

Escenario 1: salida de un objeto estructurado después de todas las demás operaciones

Tenga en cuenta el siguiente script y su salida:

PS> Get-Content scenario1.ps1
Start-Transcript scenario1.log -UseMinimalHeader
Write-Host '1'
Write-Output '2'
Get-Location
Write-Host '4'
Write-Output '5'
Stop-Transcript

PS> ./scenario1.ps1
Transcript started, output file is scenario1.log
1
2

4
Path
----
/Users/user1/src/projects/transcript
5
Transcript stopped, output file is /Users/user1/src/projects/transcript/scenario1.log

La salida de la consola muestra la salida que espera, pero no en el orden esperado. Write-Host 4 es visible antes que Get-Location porque Write-Host está optimizado para escribir directamente en el host. Hay código en la transcripción que copia la salida en el archivo de transcripción y la consola. Después, tenemos la salida normal de Get-Location y Write-Output 5 enviados como salida del script.

PS> Get-Content scenario1.log
**********************
PowerShell transcript start
Start time: 20191106114858
**********************
Transcript started, output file is s2
1
2

4
**********************
PowerShell transcript end
End time: 20191106114858
**********************

Dado que la transcripción está desactivada antes de que se cierre el script, no se representa en la transcripción. Los objetos se enviaron al siguiente consumidor de la canalización. En este caso, es Out-Default, que PowerShell insertó automáticamente. Para complicar aún más las cosas, la salida de las cadenas también está optimizada en el sistema de aplicación de formato. El primer elemento Write-Output 2 lo emite y captura la transcripción. Pero la inserción del Get-Location objeto hace que su salida se inserte en la pila de elementos que necesitan formato real, que establece un poco de estado para los objetos restantes que también pueden necesitar formato. Este es el motivo por el que el segundo Write-Output 5 no se agrega a la transcripción.

Escenario 2: Traslado de la emisión del objeto al principio

Tenga en cuenta el siguiente script y su salida:

PS> Get-Content scenario2.ps1
Start-Transcript scenario2.log -UseMinimalHeader
Get-Location
Write-Host '1'
Write-Output '2'
Get-Location
Write-Host '4'
Write-Output '5'
Stop-Transcript

PS> ./scenario2.ps1
Transcript started, output file is scenario2.log

1
4
Path
----
/Users/user1/src/projects/transcript
2
5
Transcript stopped, output file is /Users/user1/src/projects/transcript/scenario2.log

Podemos ver que los comandos Write-Host se producen antes de cualquier cosa y, a continuación, los objetos comienzan a salir. El Write-Output de una cadena obliga a que el objeto se represente en la pantalla, pero observe que la transcripción contiene solo la salida de Write-Host. Esto se debe a que esos objetos de cadena se canalizan a Out-Default para dar formato después de que el script desactive la transcripción.

PS> Get-Content scenario2.log
**********************
PowerShell transcript start
Start time: 20220606094609
**********************
Transcript started, output file is s3

1
4
**********************
PowerShell transcript end
End time: 20220606094609
**********************

Escenario 3: objeto emitido al final del script

En este escenario, la salida del objeto complejo está al final del script.

PS> Get-Content scenario3.ps1
Start-Transcript scenario3.log -UseMinimalHeader
Write-Host '1'
Write-Output '2'
Write-Host '4'
Write-Output '5'
Get-Location
Stop-Transcript

PS> ./scenario3.ps1
Transcript started, output file is scenario3.log
1
2
4
5

Path
----
/Users/user1/src/projects/transcript
Transcript stopped, output file is /Users/user1/src/projects/transcript/scenario3.log

La salida de cadena de Write-Host y Write-Output la convierte en la transcripción. Pero la salida de Get-Location se produce después de que la transcripción se haya detenido.

**********************
PowerShell transcript start
Start time: 20220606100342
**********************
Transcript started, output file is scenario3.log
1
2
4
5

**********************
PowerShell transcript end
End time: 20220606100342
**********************

Una manera de garantizar la transcripción completa

Este ejemplo es una ligera variación en el escenario original, pero ahora todo se registra en la transcripción. El código original está envuelto en un bloque de script y el formateador es invocado explícitamente a través de Out-Default.

PS> Get-Content scenario4.ps1
Start-Transcript scenario4.log -UseMinimalHeader
. {
    Write-Host '1'
    Write-Output '2'
    Get-Location
    Write-Host '4'
    Write-Output '5'
} | Out-Default
Stop-Transcript

PS> ./scenario4.ps1
Transcript started, output file is scenario4.log
1
2

4
Path
----
/Users/user1/src/projects/transcript
5

Transcript stopped, output file is /Users/user1/src/projects/transcript/scenario4.log

Observe que la última llamada de Write-Host sigue desordenada; esto se debe a la optimización en Write-Host que no entra en el flujo de salida.

PS> Get-Content scenario4.log
**********************
PowerShell transcript start
Start time: 20220606101038
**********************
Transcript started, output file is s5
1
2

4
Path
----
/Users/user1/src/projects/transcript
5

**********************
PowerShell transcript end
End time: 20220606101038
**********************