У меня есть скрипт powershell, который выполняет некоторые манипуляции с виртуальными машинами Hyper-V. У меня также есть коллекция полезных функций, в том числе функция, которая запускает транскрипт для скрипта, если транскрипт еще не запущен. Функция запуска стенограммы работала довольно долго.
Пару дней спустя go я исследовал ошибку, возникшую при параллельном запуске сценария два раза, и заметил, что одна из стенограмм скучал. Но программа просмотра событий четко показывает, как виртуальные машины выполняются сценарием, в котором отсутствует стенограмма. И есть другие доказательства того, что сценарий выполнялся в течение 20 минут или около того, прежде чем произошла ошибка (последующий сценарий выполнялся с расшифровкой через 20 минут).
Я понимаю, что этот вопрос является общим c и открытым, но какие-либо мысли о том, что может привести к тому, что стенограмма не будет генерироваться? Все мои сценарии настроены так, чтобы останавливаться на ошибках, поэтому, если Start-Transcript
не удастся, сценарий остановится. Но стенограмма нигде не найдена ... Не в каталоге моих транскриптов go to или в каталоге транскриптов по умолчанию, когда не указан путь к Start-Transcript
Вот мой код, который обрабатывает условные выражения запуск / остановка стенограммы, если это полезно. Мой скрипт верхнего уровня вызывает StartTranscriptIfAppropriate
:
Set-Variable -name TranscriptStartedPropertyName -opt ReadOnly -value 'PSUTIL_Logging_TranscriptStarted' -force
Set-Variable -name TranscriptPathPrivatePropertyName -opt ReadOnly -value 'PSUTIL_Logging_TranscriptPathPrivate' -force
function GetTopLevelScript
{
$callstack = get-pscallstack
$offset = -1
while ($callstack[$offset].GetScriptLocation() -eq '<no file>')
{
$offset = $offset - 1
}
$fullPath = $callstack[$offset].ScriptName
return $fullPath
}
function StartTranscriptIfAppropriate
{
$transcriptStarted = [bool](Get-Variable -name $TranscriptStartedPropertyName -ErrorAction Ignore)
if (-not $transcriptStarted)
{
$fullPath = GetTopLevelScript
if ($fullPath)
{
$name = Split-Path -Path $fullPath -Leaf
}
else
{
$name = "UnknownCallingScript"
}
$logDirectory = "c:\mylogdirectory"
md -force $logDirectory | out-null
$logFinalPath = "$logDirectory\$(Get-Date -Format o | foreach {$_ -replace ":", "."})_$name.log"
Start-Transcript $logFinalPath | Write-Host
Set-Variable -scope 1 -name $TranscriptStartedPropertyName -value $True
Set-Variable -scope 1 -option private -name $TranscriptPathPrivatePropertyName -value $logFinalPath
}
}
function GetTranscriptPathIfWeStartedIt
{
[CmdletBinding()]
Param(
[switch]$IncreaseScopeForNestedCall
)
$scope = 1
if ($IncreaseScopeForNestedCall)
{
$scope = 2
}
$transcriptPath = (Get-Variable -scope $scope -name $TranscriptPathPrivatePropertyName -ErrorAction Ignore -ValueOnly)
if ($transcriptPath)
{
return $transcriptPath
}
return $null
}
function ConditionalStopTranscript
{
#We had to move away from getting PSCommandPath because it was incorrect when run from Start-Job
$invocation = Get-Variable -scope 1 -name MyInvocation -ValueOnly
$immediateCallerPath = $invocation.mycommand.path
Write-Host "Stopping script at $immediateCallerPath"
if ($(GetTranscriptPathIfWeStartedIt -IncreaseScopeForNestedCall))
{
Stop-Transcript | Write-Host
}
}```