Поделиться через


about_Debuggers

Краткое описание

Описывает отладчик PowerShell.

Длинное описание

Отладка — это процесс проверки скрипта во время его выполнения для выявления и исправления ошибок в инструкциях скрипта. Отладчик PowerShell поможет вам изучить и определить ошибки и неэффективность в сценариях, функциях, командах, конфигурациях или выражениях PowerShell Desired State Configuration (DSC).

Начиная с PowerShell 5.0 отладчик PowerShell был обновлен для отладки скриптов, функций, команд, конфигураций или выражений, работающих в консоли или интегрированной среде сценариев Windows PowerShell (ISE) на удаленных компьютерах.

Заметка

Среда сценариев Windows PowerShell поддерживает только Windows PowerShell. Для PowerShell 6 и более поздних версий необходимо использовать Visual Studio Code с расширением для PowerShell. Дополнительные сведения см. в разделе Отладка с помощью Visual Studio Code.

Командлеты отладчика

Отладчик PowerShell включает следующий набор командлетов:

  • Set-PSBreakpoint: задает точки останова в строках, переменных и командах.
  • Get-PSBreakpoint: получает точки останова в текущем сеансе.
  • Disable-PSBreakpoint. Отключение точек останова в текущем сеансе.
  • Enable-PSBreakpoint: повторно включает точки останова в текущем сеансе.
  • Remove-PSBreakpoint: удаляет точки останова из текущего сеанса.
  • Get-PSCallStack: отображает текущий стек вызовов.

Запуск и остановка отладчика

Чтобы запустить отладчик, задайте одну или несколько точек останова, а затем выполните скрипт, команду или функцию, которую требуется выполнить отладку.

При достижении точки останова, остановки выполнения и управления переключается на отладчик.

Чтобы остановить отладчик, запустите скрипт, команду или функцию до завершения. Или введите stop или t.

Команды отладчика

При использовании отладчика в консоли PowerShell используйте следующие команды для управления выполнением. В среде сценариев Windows PowerShell используйте команды в меню отладки.

Заметка

Сведения об использовании отладчика в других ведущих приложениях см. в документации по хост-приложениям.

  • s, StepInto: выполняет следующую инструкцию, а затем останавливается.

  • v, StepOver: выполняет следующую инструкцию, но пропускает функции и вызовы. Пропущенные инструкции выполняются, но не выполняются.

  • Ctrl+Break. (Разорвать все в интегрированной среде сценариев) прерывает выполнение скрипта в консоли PowerShell или интегрированной среде сценариев Windows PowerShell. Обратите внимание, что ctrl+прерывание в Windows PowerShell 2.0, 3.0 и 4.0 закрывает программу. Прерывание работы всех работает как на локальных, так и на удаленных интерактивных сценариях.

  • o, StepOut: шаги из текущей функции; до одного уровня, если вложено. Если в основном тексте, он продолжается до конца или следующей точки останова. Пропущенные инструкции выполняются, но не выполняются.

  • c, Continue: продолжает выполняться до завершения скрипта или до достижения следующей точки останова. Пропущенные инструкции выполняются, но не выполняются.

  • l, List: отображает часть выполняемого скрипта. По умолчанию отображается текущая строка, пять предыдущих строк и 10 последующих строк. Чтобы продолжить перечисление скрипта, нажмите клавишу ВВОД.

  • l <m>, List: отображает 16 строк скрипта, начиная с номера строки, указанной <m>.

  • l <m> <n>, List: отображает <n> строки скрипта, начиная с номера строки, указанной <m>.

  • q, Stop, Exit: останавливает выполнение скрипта и завершает отладчик. При отладке задания с помощью командлета Debug-Job команда Exit отсоединяет отладчик и позволяет заданию продолжать работу.

  • k, Get-PSCallStack: отображает текущий стек вызовов.

  • <Enter>: повторяет последнюю команду, если она была Step (s), StepOver (v) или List (l). В противном случае представляет действие отправки.

  • ?, h: отображает справку отладчика.

Чтобы выйти из отладчика, можно использовать Stop (q).

Начиная с PowerShell 5.0, можно запустить команду Exit, чтобы выйти из вложенного сеанса отладки, запущенного с помощью Debug-Job или Debug-Runspace.

С помощью этих команд отладчика можно запустить скрипт, остановиться на точке озабоченности, проанализировать значения переменных и состояние системы и продолжить выполнение скрипта до тех пор, пока не удается определить проблему.

Заметка

При шаге в инструкцию с оператором перенаправления, например >, отладчик PowerShell выполняет все остальные инструкции в скрипте.

Отображение значений переменных скрипта

Пока вы находитесь в отладчике, вы также можете ввести команды, отобразить значение переменных, использовать командлеты и запускать скрипты в командной строке. Текущее значение всех переменных можно отобразить в скрипте, который выполняется отладка, за исключением следующих автоматических переменных:

$_
$args
$input
$MyInvocation
$PSBoundParameters

При отображении значения любой из этих переменных вы получаете значение этой переменной для внутреннего конвейера, который использует отладчик, а не значение переменной в скрипте.

Чтобы отобразить значение этих переменных для отлаживаемого скрипта, добавьте строки в скрипт, чтобы сохранить эти значения в новую переменную. Установите точку останова после этих новых строк. Затем можно отобразить значение новой переменной.

Например

$scriptArgs = $args
$scriptname = $MyInvocation.PSCommandPath

Среда отладчика

При достижении точки останова введите среду отладчика. Командная строка изменяется таким образом, что начинается с "[DBG]:". Кроме того, в некоторых ведущих приложениях, таких как консоль PowerShell, откроется вложенный запрос для отладки. Вы можете обнаружить вложенный запрос, повторяя символы большего значения (ASCII 62), которые отображаются в командной строке.

Дополнительные сведения о настройке запроса см. в about_Prompts.

Уровень вложения можно найти с помощью автоматической переменной $NestedPromptLevel. Автоматическая переменная, $PSDebugContext, определяется в локальной области. Вы можете использовать наличие переменной $PSDebugContext, чтобы определить, выполняется ли вы в отладчике.

Например:

if ($PSDebugContext) {"Debugging"} else {"Not Debugging"}

Значение переменной $PSDebugContext можно использовать в отладке.

[DBG]: PS>>> $PSDebugContext.InvocationInfo

Name   CommandLineParameters  UnboundArguments  Location
----   ---------------------  ----------------  --------
=      {}                     {}                C:\ps-test\vote.ps1 (1)

Отладка и область

Разрыв в отладчике не изменяет область, в которой вы работаете, но при достижении точки останова в скрипте вы переходите в область скрипта. Область скрипта является дочерним элементом области, в которой вы запустили отладчик.

Чтобы найти переменные и псевдонимы, определенные в области скрипта, используйте параметр Scope командлетов Get-Alias или Get-Variable.

Например, следующая команда получает переменные в локальной области (скрипта):

Get-Variable -Scope 0

Это удобный способ увидеть только переменные, определенные в скрипте, и их определение во время отладки.

Отладка в командной строке

При установке переменной точки останова или командной точки останова можно задать точку останова только в файле скрипта. Однако по умолчанию точка останова устанавливается на все, что выполняется в текущем сеансе.

Например, если задать точку останова в переменной $name, отладчик прерывает работу любой переменной $name в любом скрипте, команде, функции, командлете скрипта или выражении, которое выполняется до отключения или удаления точки останова.

Это позволяет выполнять отладку скриптов в более реалистичном контексте, в котором они могут влиять на функции, переменные и другие скрипты в сеансе и в профиле пользователя.

Точки останова строки относятся к файлам скриптов, поэтому они задаются только в файлах скриптов.

Функции отладки

При установке точки останова для функции, которая содержит begin, processи end разделы, отладчик прерывается в первой строке каждого раздела.

Например:

function Test-Cmdlet {
    begin {
        Write-Output "Begin"
    }
    process {
        Write-Output "Process"
    }
    end {
        Write-Output "End"
    }
}

C:\PS> Set-PSBreakpoint -Command Test-Cmdlet

C:\PS> Test-Cmdlet

Begin
Entering debug mode. Use h or ? for help.

Hit Command breakpoint on 'prompt:Test-Cmdlet'

Test-Cmdlet

[DBG]: C:\PS> c
Process
Entering debug mode. Use h or ? for help.

Hit Command breakpoint on 'prompt:Test-Cmdlet'

Test-Cmdlet

[DBG]: C:\PS> c
End
Entering debug mode. Use h or ? for help.

Hit Command breakpoint on 'prompt:Test-Cmdlet'

Test-Cmdlet

[DBG]: C:\PS>

Отладка удаленных скриптов

Вы можете запустить Enter-PSSession для запуска интерактивного удаленного сеанса PowerShell, в котором можно задать точки останова и отладить файлы скриптов и команды на удаленном компьютере. Enter-PSSession позволяет повторно подключить отключенный сеанс, выполняющий скрипт или команду на удаленном компьютере. Если запущенный скрипт попадает в точку останова, сеанс клиента автоматически запускает отладчик. Если отключенный сеанс, выполняющий скрипт, уже попал в точку останова, Enter-PSSession автоматически запускает отладчик командной строки при повторном подключении к сеансу.

В следующем примере показано, как это работает. Точки останова заданы в строках 6, 11, 22 и 25 скрипта. При запуске отладчика есть два идентифицировать изменения в запросе:

  • Имя компьютера, на котором выполняется сеанс
  • Запрос DBG, который позволяет узнать, что вы находитесь в режиме отладки
Enter-PSSession -Cn localhost
[localhost]: PS C:\psscripts> Set-PSBreakpoint .\ttest19.ps1 6, 11, 22, 25

ID Script          Line     Command          Variable          Action
-- ------          ----     -------          --------          ------
0 ttest19.ps1          6
1 ttest19.ps1          11
2 ttest19.ps1          22
3 ttest19.ps1          25

[localhost]: PS C:\psscripts> .\ttest19.ps1
Hit Line breakpoint on 'C:\psscripts\ttest19.ps1:11'

At C:\psscripts\ttest19.ps1:11 char:1
+ $winRMName = "WinRM"
# + ~

[localhost]: [DBG]: PS C:\psscripts>> list

6:      1..5 | foreach { sleep 1; Write-Output "hello2day $_" }
7:  }
# 8:

9:  $count = 10
10:  $psName = "PowerShell"
11:* $winRMName = "WinRM"
12:  $myVar = 102
# 13:

14:  for ($i=0; $i -lt $count; $i++)
15:  {
16:      sleep 1
17:      Write-Output "Loop iteration is: $i"
18:      Write-Output "MyVar is $myVar"
# 19:

20:      hello2day
# 21:


[localhost]: [DBG]: PS C:\psscripts>> stepover
At C:\psscripts\ttest19.ps1:12 char:1
+ $myVar = 102
# + ~

[localhost]: [DBG]: PS C:\psscripts>> quit
[localhost]: PS C:\psscripts> Exit-PSSession
PS C:\psscripts>

Примеры

Этот тестовый скрипт обнаруживает версию PowerShell и отображает соответствующее сообщение с версией. Она включает функцию, вызов функции и переменную.

Следующая команда отображает содержимое файла тестового скрипта:

PS C:\PS-test>  Get-Content test.ps1

function psversion {
  "PowerShell " + $PSVersionTable.PSVersion
  if ($PSVersionTable.PSVersion.Major -lt 7) {
    "Upgrade to PowerShell 7!"
  }
  else {
    "Have you run a background job today (Start-Job)?"
  }
}

$scriptName = $MyInvocation.PSCommandPath
psversion
"Done $scriptName."

Чтобы начать, задайте точку останова в точке интереса к скрипту, например строку, команду, переменную или функцию.

Начните с создания точки останова строки в первой строке скрипта Test.ps1 в текущем каталоге.

PS C:\ps-test> Set-PSBreakpoint -Line 1 -Script test.ps1

Команда возвращает объект System.Management.Automation.LineBreakpoint.

Column     : 0
Line       : 1
Action     :
Enabled    : True
HitCount   : 0
Id         : 0
Script     : C:\ps-test\test.ps1
ScriptName : C:\ps-test\test.ps1

Теперь запустите скрипт.

PS C:\ps-test> .\test.ps1

Когда скрипт достигает первой точки останова, сообщение точки останова указывает, что отладчик активен. Он описывает точку останова и просматривает первую строку скрипта, которая является объявлением функции. Командная строка также изменяется, чтобы указать, что отладчик имеет элемент управления.

Строка предварительного просмотра содержит имя скрипта и номер строки предварительной команды.

Entering debug mode. Use h or ? for help.

Hit Line breakpoint on 'C:\ps-test\test.ps1:1'

test.ps1:1   function psversion {
DBG>

Используйте команду Step (s), чтобы выполнить первую инструкцию в скрипте и просмотреть следующую инструкцию. Следующая инструкция использует автоматическую переменную $MyInvocation для задания значения переменной $scriptName пути и имени файла скрипта.

DBG> s
test.ps1:11  $scriptName = $MyInvocation.PSCommandPath

На этом этапе переменная $scriptName не заполняется, но вы можете проверить значение переменной, отображая его значение. В этом случае значение равно $null.

DBG> $scriptname
DBG>

Используйте другую команду Step (s) для выполнения текущей инструкции и предварительного просмотра следующей инструкции в скрипте. Следующая инструкция вызывает функцию psversion.

DBG> s
test.ps1:12  psversion

На этом этапе $scriptName переменная заполняется, но проверяется значение переменной. В этом случае значение устанавливается в путь к скрипту.

DBG> $scriptName
C:\ps-test\test.ps1

Используйте другую команду Step для выполнения вызова функции. Нажмите клавишу ВВОД или введите "s" для шага.

DBG> s
test.ps1:2       "PowerShell " + $PSVersionTable.PSVersion

Сообщение отладки содержит предварительный просмотр инструкции в функции. Чтобы выполнить эту инструкцию и просмотреть следующую инструкцию в функции, можно использовать команду Step. Но в этом случае используйте команду StepOut (o). Он завершает выполнение функции (если она не достигает точки останова) и выполняет шаги к следующей инструкции в скрипте.

DBG> o
Windows PowerShell 2.0
Have you run a background job today (Start-Job)?
test.ps1:13  "Done $scriptName"

Так как мы имеем последнюю инструкцию в скрипте, команды Step, StepOut и Continue имеют тот же эффект. В этом случае используйте StepOut (o).

Done C:\ps-test\test.ps1
PS C:\ps-test>

Команда StepOut выполняет последнюю команду. Стандартная командная строка указывает, что отладчик завершил работу и вернул элемент управления обработчику команд.

Теперь запустите отладчик еще раз. Сначала для удаления текущей точки останова используйте командлеты Get-PSBreakpoint и Remove-PSBreakpoint. (Если вы считаете, что вы можете повторно использовать точку останова, используйте командлет Disable-PSBreakpoint вместо Remove-PSBreakpoint.)

PS C:\ps-test> Get-PSBreakpoint | Remove-PSBreakpoint

Эту команду можно аббревиатировать следующим образом:

PS C:\ps-test> gbp | rbp

Или выполните команду, написав функцию, например следующую функцию:

function delbr { gbp | rbp }

Теперь создайте точку останова в переменной $scriptname.

PS C:\ps-test> Set-PSBreakpoint -Variable scriptname -Script test.ps1

Вы можете сократить команду следующим образом:

PS C:\ps-test> sbp -V scriptname -S test.ps1

Теперь запустите скрипт. Скрипт достигает точки останова переменной. По умолчанию используется режим записи, поэтому выполнение останавливается непосредственно перед инструкцией, которая изменяет значение переменной.

PS C:\ps-test> .\test.ps1
Hit Variable breakpoint on 'C:\ps-test\test.ps1:$scriptName'
(Write access)

test.ps1:11  $scriptName = $MyInvocation.PSCommandPath
DBG>

Отображение текущего значения переменной $scriptName, которая $null.

DBG> $scriptName
DBG>

Используйте команду Step (s) для выполнения инструкции, заполняющей переменную. Затем отобразите новое значение переменной $scriptName.

DBG> $scriptName
C:\ps-test\test.ps1

Используйте команду Step (s), чтобы просмотреть следующую инструкцию в скрипте.

DBG> s
test.ps1:12  psversion

Следующая инструкция — это вызов функции psversion. Чтобы пропустить функцию, но по-прежнему выполнить ее, используйте команду StepOver (v). Если вы уже находитесь в функции при использовании StepOver, она не действует. Отображается вызов функции, но он не выполняется.

DBG> v
Windows PowerShell 2.0
Have you run a background job today (Start-Job)?
test.ps1:13  "Done $scriptName"

Команда StepOver выполняет функцию, и она предварительно просматривает следующую инструкцию в скрипте, которая выводит окончательную строку.

Чтобы выйти из отладчика, используйте команду Stop (t). Командная строка возвращается к стандартной командной строке.

C:\ps-test>

Чтобы удалить точки останова, используйте командлеты Get-PSBreakpoint и Remove-PSBreakpoint.

PS C:\ps-test> Get-PSBreakpoint | Remove-PSBreakpoint

Создайте новую точку останова команды в функции psversion.

PS C:\ps-test> Set-PSBreakpoint -Command psversion -Script test.ps1

Вы можете сократить эту команду следующим образом:

PS C:\ps-test> sbp -C psversion -S test.ps1

Теперь запустите скрипт.

PS C:\ps-test> .\test.ps1
Hit Command breakpoint on 'C:\ps-test\test.ps1:psversion'

test.ps1:12  psversion
DBG>

Скрипт достигает точки останова при вызове функции. На этом этапе функция еще не была вызвана. Это дает возможность использовать параметр Action Set-PSBreakpoint для задания условий выполнения точки останова или выполнения подготовительных или диагностических задач, таких как запуск журнала или вызов скрипта диагностики или безопасности.

Чтобы задать действие, используйте команду Continue (c) для выхода из скрипта и команду Remove-PSBreakpoint для удаления текущей точки останова. (Точки останова доступны только для чтения, поэтому вы не можете добавить действие в текущую точку останова.)

DBG> c
Windows PowerShell 2.0
Have you run a background job today (Start-Job)?
Done C:\ps-test\test.ps1

PS C:\ps-test> Get-PSBreakpoint | Remove-PSBreakpoint
PS C:\ps-test>

Теперь создайте новую точку останова команды с действием. Следующая команда задает точку останова команды с действием, которое регистрирует значение переменной $scriptName при вызове функции. Так как ключевое слово break не используется в действии, выполнение не останавливается. Обратная черта (`) — это символ продолжения строки.

PS C:\ps-test> Set-PSBreakpoint -Command psversion -Script test.ps1  `
-Action { Add-Content "The value of `$scriptName is $scriptName." `
-Path action.log}

Можно также добавить действия, которые задают условия для точки останова. В следующей команде точка останова выполняется только в том случае, если для политики выполнения задано значение RemoteSigned, самая ограничивающая политика, которая по-прежнему позволяет запускать скрипты.

PS C:\ps-test> Set-PSBreakpoint -Script test.ps1 -Command psversion `
-Action { if ((Get-ExecutionPolicy) -eq "RemoteSigned") { break }}

Ключевое слово break в действии направляет отладчик для выполнения точки останова. Вы также можете использовать ключевое слово continue для направления отладчика для выполнения без нарушения. Так как ключевое слово по умолчанию continue, необходимо указать break, чтобы остановить выполнение.

Теперь запустите скрипт.

PS C:\ps-test> .\test.ps1
Hit Command breakpoint on 'C:\ps-test\test.ps1:psversion'

test.ps1:12  psversion

Так как политика выполнения имеет значение RemoteSigned, выполнение останавливается при вызове функции.

На этом этапе может потребоваться проверить стек вызовов. Используйте командлет Get-PSCallStack или команду отладчика Get-PSCallStack (k). Следующая команда получает текущий стек вызовов.

DBG> k
2: prompt
1: .\test.ps1: $args=[]
0: prompt: $args=[]

В этом примере показано лишь несколько способов использования отладчика PowerShell.

Другие функции отладки в PowerShell

Помимо отладчика PowerShell, PowerShell включает несколько других функций, которые можно использовать для отладки скриптов и функций.

  • Командлет Set-PSDebug предлагает очень основные функции отладки скриптов, включая пошаговое выполнение и трассировку.

  • Используйте командлет Set-StrictMode для обнаружения ссылок на неинициализированные переменные, ссылки на несуществующие свойства объекта и синтаксис функции, недопустимый.

  • Добавьте диагностические инструкции в скрипт, например инструкции, отображающие значение переменных, инструкции, которые считывают входные данные из командной строки или инструкции, сообщающие об текущей инструкции. Используйте командлеты, содержащие команду записи для этой задачи, например Write-Host, Write-Debug, Write-Warningи Write-Verbose.

См. также