Отслеживание источника вывода в скрипте Powershell - PullRequest
0 голосов
/ 22 ноября 2018

Можно ли отследить, откуда выводится (на консоль) сценарий Powershell?У меня есть скрипт, который выводит информацию для меня, но я не уверен, какая строка выводит.Можно ли, например, использовать Set-PSBreakpoint и сказать ему, чтобы он прерывался при возврате информации на консоль?

Приветствия


Я получаю сотни "Ложь"возвращаются по своим линиям.Вот часть кода, из которой поступает вывод:

    $ar = Function-which_returns_array_of_objects
    $gr = Function-which_returns_array_of_objects

    Write-Host "To begin with..."
    Write-Host "$($ar.count) assets"
    Write-Host "$($gr.count) goods"

    foreach($asset in $ar){
        if(!(Test-NoNA -string $asset.Serial)){continue}

        #See if the particular serial number exists in Goods Received
        $found = @()
        $gr | Where {$_.SerialNumber -eq $asset.serial} | %{
            $found += $_
            # and then mark the entry as one that has to be deleted from GR
            $_.Delete = "YES"
        }
        if($found.count -eq 1){
            #Serial Number has been found once in GR
            #We want to check its PN...
            if(Test-NoNA -string $found.PartNumber -and $found.PartNumber -ne $asset.Model){
                #add it to the asset if its good and not the same as the model number...
                $asset.PartNumber -eq $found.PartNumber
            }
        }elseif(!$found -or $found.count -eq 0){
            #No entries found in GR
            #Shouldn't be the case but doesn't actually do any damage as we'd be deleting the GR entry anyway
        }elseif($found.count -gt 1){
            #More than one match for the SN - probably means a SN like "N/A" has got through the earlier checks
            Write-Warning "More than one match for SN: '$($asset.serial)'"
        }else{
            #Default catcher
            Write-Warning "Unknown Error for SN: '$($asset.serial)'"
        }
    }

Также здесь есть Test-NoNA:

function Test-NoNA($string){
#check that the given string is not blank, N/A, ?, etc. Returns true if string is good
if($string -and $string -ne "" -and $string -ne "N/A" -and $string -ne "NA" -and $string -ne '?' -and $string -isnot [System.DBNull]){return $true}
}

Ответы [ 2 ]

0 голосов
/ 23 ноября 2018

К сожалению,

  • Set-PSBreakpoint -Command хорошо работает с явными вызовами командлетов ,

    • Например,вызовы Write-Output и Write-Host в сценарии ./myscript.ps1 могут вызвать взлом в отладчике с помощью предварительного вызова Set-PSBreakpoint -Command Write-* ./myscript.ps1,
  • , но делает не работа с неявным выводом из операторов, выходные данные которых не перехвачены и не перенаправлены (например, 'foo', 1 + 2, Get-Date).

В данном конкретном случае такие операторы, как $asset.PartNumber -eq $found.PartNumber, вызывали нежелательный вывод из-за путаницы с оператором -eq (сравнение) с оператором = (назначение), так какдиагноз Lee_Daily .-eq производит вывод (логический результат сравнения), тогда как = - нет.

Обходные пути :

  • Запустите Set-PSDebug -Trace 1 перед вызовом вашего скрипта, который печатает каждую строку исходного кода перед выводом, который он выдает с, если таковой имеется.-Trace 2 предоставляет дополнительные сведения.

  • Используйте следующую технику, которая сообщает вам номер первой строки, которая дает успешный вывод ,неявно или явно;обратите внимание, однако, что выполнение сценария прервано в этот момент:

    try { ./myscript.ps1 | Write-Error -EA Stop } catch { "$_"; $_.ScriptStackTrace }
    
    • Выходные данные сценария успешно передаются в Write-Error, который перенаправляет (строковую версию)вывод в поток ошибок PowerShell, с -EA Stop (сокращение от -ErrorAction Stop), вызывающее прерывание выполнения при отправке вывода в поток ошибок;Затем блок catch выводит строковую версию результирующей записи об ошибке (которая сама по себе является строковой версией исходного вывода), за которой следует трассировка стека вызова сценария, первая строка которой показывает номер строки, которая произвелавыходные данные.
    • Примечание. Этот метод не будет работать, если в сценарии произойдет ошибка, определяющая оператор перед первым успешным выводом, что, однако, редко.
  • Если вы хотите проверить состояние выполнения скрипта в данной строке , скажем 15:

    • Set-PSBreakpoint -Script ./myscript.ps1 -Line 15

    • В качестве альтернативы, в PSv5 +, если вариант (временно) является модификацией сценария, поместите вызов Wait-Debugger в свой сценарий в том месте, где вы хотите проникнуть в отладчик..

  • Используйте возможности отладки Код Visual Studio с расширением PowerShell для установить точки останова и / или пройти черезвыполнение вашего сценария оператор за оператором.

    • В качестве альтернативы используйте Set-PSDebug -Step для эквивалентной операции непосредственно в окне PowerShell.
0 голосов
/ 22 ноября 2018

Да, попробуйте это.Это должно прерваться, где бы ни находился оператор write.

  Set-PSBreakpoint -Script Sample.ps1 -Command "write*"

Эта команда устанавливает точку останова для каждой команды в сценарии Sample.ps1, которая начинается с записи, например Write-Host.Подробнее см. документы

...