PowerShell transkriptlerinin sınırlamaları


Write-Host çıktısını çıktı nesneleri, dizeler ve PowerShell transkripsiyonuyla karıştırmak karmaşıktır. Betik ile transkripsiyonun PowerShell ardışık düzenleriyle çalışma şekli arasında beklenmedik sonuçlara yol açabilecek ince bir etkileşim vardır.

Komut dosyanızdan nesneler çıkardığınızda, bu nesnelerin biçimlendirmesi Out-Default tarafından gerçekleştirilir. Ancak biçimlendirme, komut dosyası tamamlandıktan ve transkripsiyon durdurulduktan sonra gerçekleşebilir. Bu, çıktının yazıya geçirilmediği anlamına gelir. Dizeler farklı şekilde işlenir. Bazen dize çıktısı biçimlendirmeden geçirilir, ancak her zaman değil. Write-Host, ana bilgisayar işlemine anında yazma işlemi gerçekleştirir. Write-Object biçimlendirme sistemi aracılığıyla gönderilir. Karmaşık nesnelerin çıktısını ana bilgisayara yapılan yazma işlemleriyle birleştirmek, transkriptte neyin günlüğe kaydedildiğini tahmin etmeyi zorlaştırır.

Senaryo 1 - Tüm diğer işlemlerin sonunda yapılandırılmış bir nesnenin çıktısı

Aşağıdaki betiği ve çıktısını göz önünde bulundurun:

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

Konsolun çıktısı beklediğiniz çıktıyı gösterir, ancak beklediğiniz sırada değil. Write-Host 4, Get-Location'dan önce görünür çünkü Write-Host doğrudan ana bilgisayara yazacak şekilde optimize edilmiştir. Transkripsiyonda çıktıyı transkript dosyasına ve konsola kopyalayan kod vardır. Daha sonra betiğin çıktısı olarak gönderilen Get-Location ve Write-Output 5'in normal çıktısına sahibiz.

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

Betikten çıkmadan önce transkripsiyon kapatıldığı için transkripsiyonda işlenmez. Nesneler işlem hattındaki bir sonraki tüketiciye gönderildi. Bu durumda, PowerShell'in otomatik olarak eklediği Default Dışı'dır. İşleri daha da karmaşık hale getirmek için, dizelerin çıktısı da biçimlendirme sisteminde optimize edilmiştir. İlk Yazma-Çıktı 2 transkript tarafından yayılır ve yakalanır. Ancak Get-Location nesnesinin eklenmesi, çıktısının gerçek biçimlendirme gerektiren şeyler yığınına itilmesine neden olur; bu da biçimlendirmeye ihtiyaç duyabilecek kalan nesneler için bir miktar durum belirler. İkinci Yazma-Çıktı 5'in transkripte eklenmemesinin nedeni budur.

Senaryo 2 - Nesne emisyonunu başlangıca taşıyın

Aşağıdaki betiği ve çıktısını göz önünde bulundurun:

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

Her şeyden önce Write-Host komutlarının gerçekleştiğini, ardından nesnelerin ortaya çıkmaya başladığını görüyoruz. Bir dizenin Write-Output'u, nesnenin ekranda görüntülenmesini zorlar, ancak transkriptin yalnızca Write-Host çıktısını içerdiğine dikkat edin. Bunun nedeni, bu dize nesnelerinin, komut dosyası transkripsiyonu kapattıktan sonra biçimlendirme için Out-Default'a aktarılmasıdır.

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

Senaryo 3 - Komut dosyasının sonunda yayılan nesne

Bu senaryo için karmaşık nesnenin çıktısı betiğin sonundadır.

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

Hem Write-Host hem de Write-Object'ten gelen dize çıktısı onu transkripte dönüştürür. Ancak Get-Location çıktısı, transkripsiyon durdurulduktan sonra gerçekleşir.

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

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

Tam transkripsiyon sağlamanın bir yolu

Bu örnek, orijinal senaryonun küçük bir varyasyonudur, ancak artık her şey transkripte kaydedilmektedir. Orijinal kod bir komut dosyası bloğuna sarılır ve biçimlendirici açıkça Out-Default aracılığıyla çağrılır.

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

Son Write-Host çağrısının hâlâ bozuk olduğuna dikkat edin; bunun nedeni, Write-Host'taki çıktı akışına girmeyen optimizasyondur.

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

İlgili makaleler