Batasan transkrip PowerShell

Write-Host Mencampur output dengan objek output, string, dan transkripsi PowerShell rumit. Ada interaksi halus antara skrip dan cara kerja transkripsi dengan alur PowerShell yang dapat memiliki hasil yang tidak terduga.

Saat Anda memancarkan objek dari skrip Anda, pemformatan objek tersebut ditangani oleh Out-Default. Tetapi pemformatan dapat terjadi setelah skrip selesai dan transkripsi berhenti. Ini berarti bahwa output tidak ditranskripsikan. String ditangani secara berbeda. Terkadang output string diteruskan melalui pemformatan, tetapi tidak selalu. Write-Host segera menulis ke proses host. Write-Object dikirim melalui sistem pemformatan. Menggabungkan output objek kompleks dengan penulisan ke host menyulitkan untuk memprediksi apa yang dicatat dalam transkrip.

Skenario 1 - Output objek terstruktur di akhir semua operasi lainnya

Pertimbangkan skrip berikut dan outputnya:

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

Output ke konsol menunjukkan output yang Anda harapkan, tetapi tidak sesuai urutan yang Anda harapkan. Write-Host 4 terlihat sebelumnya Get-Location karena Write-Host dioptimalkan untuk menulis langsung ke host. Ada kode dalam transkripsi yang menyalin output ke file transkrip dan konsol. Kemudian kita memiliki output reguler dan Get-LocationWrite-Output 5 dikirim sebagai output dari skrip.

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
**********************

Karena transkripsi dimatikan sebelum skrip keluar, transkrip tidak dirender dalam transkrip. Objek dikirim ke konsumen berikutnya dalam alur. Dalam hal ini, ini adalah Out-Default, yang dimasukkan PowerShell secara otomatis. Untuk mempersulit hal-hal lebih lanjut, output string juga dioptimalkan dalam sistem pemformatan. Yang pertama Write-Output 2 dipancarkan dan ditangkap oleh transkrip. Tetapi penyisipan Get-Location objek menyebabkan outputnya didorong ke tumpukan hal-hal yang membutuhkan pemformatan aktual, yang mengatur sedikit status untuk objek yang tersisa yang juga mungkin memerlukan pemformatan. Inilah sebabnya mengapa yang kedua Write-Output 5 tidak ditambahkan ke transkrip.

Skenario 2 - Memindahkan emisi objek ke awal

Pertimbangkan skrip berikut dan outputnya:

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

Kita dapat melihat bahwa Write-Host perintah terjadi sebelum apa pun, dan kemudian objek mulai keluar. Write-Output Dari string memaksa objek untuk dirender ke layar, tetapi perhatikan bahwa transkrip hanya berisi output dari Write-Host. Itu karena objek string tersebut disalurkan ke Out-Default untuk pemformatan setelah skrip dinonaktifkan transkripsi.

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
**********************

Skenario 3 - Objek yang dipancarkan di akhir skrip

Untuk skenario ini, output objek kompleks berada di akhir skrip.

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

Output string dari keduanya Write-Host dan Write-Object membuatnya menjadi transkrip. Namun, output dari Get-Location terjadi setelah transkripsi berhenti.

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

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

Cara untuk memastikan transkripsi penuh

Contoh ini adalah sedikit variasi pada skenario asli, tetapi sekarang semuanya dicatat ke transkrip. Kode asli dibungkus dalam blok skrip dan formatter secara eksplisit dipanggil melalui 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

Perhatikan bahwa panggilan terakhir Write-Host masih tidak berurutan, itu karena pengoptimalan dalam Write-Host yang tidak masuk ke aliran output.

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
**********************