about_Debuggers

Krótki opis

Opisuje debuger programu PowerShell.

Długi opis

Debugowanie to proces badania skryptu podczas jego uruchamiania w celu identyfikowania i poprawiania błędów w instrukcjach skryptu. Debuger programu PowerShell może pomóc w zbadania i zidentyfikowania błędów i nieefektywności w skryptach, funkcjach, poleceniach, konfiguracjach żądanego stanu programu PowerShell (DSC) lub wyrażeniach.

Począwszy od programu PowerShell 5.0, debuger programu PowerShell został zaktualizowany do debugowania skryptów, funkcji, poleceń, konfiguracji lub wyrażeń uruchomionych w konsoli lub zintegrowanego środowiska skryptów programu Windows PowerShell (ISE) na komputerach zdalnych.

Uwaga

Program Windows PowerShell ISE obsługuje tylko program Windows PowerShell. W przypadku programu PowerShell 6 i nowszych należy użyć programu Visual Studio Code z rozszerzeniem dla programu PowerShell. Aby uzyskać więcej informacji, zobacz Debugowanie za pomocą programu Visual Studio Code.

Polecenia cmdlet debugera

Debuger programu PowerShell zawiera następujący zestaw poleceń cmdlet:

  • Set-PSBreakpoint: Ustawia punkty przerwania w wierszach, zmiennych i poleceniach.
  • Get-PSBreakpoint: pobiera punkty przerwania w bieżącej sesji.
  • Disable-PSBreakpoint: wyłącza punkty przerwania w bieżącej sesji.
  • Enable-PSBreakpoint: Ponownie włącza punkty przerwania w bieżącej sesji.
  • Remove-PSBreakpoint: usuwa punkty przerwania z bieżącej sesji.
  • Get-PSCallStack: wyświetla bieżący stos wywołań.

Uruchamianie i zatrzymywanie debugera

Aby uruchomić debuger, ustaw co najmniej jeden punkt przerwania, a następnie uruchom skrypt, polecenie lub funkcję, którą chcesz debugować.

Gdy osiągniesz punkt przerwania, wykonywanie zostanie zatrzymane, a kontrolka zostanie przekazana do debugera.

Aby zatrzymać debuger, uruchom skrypt, polecenie lub funkcję, dopóki nie zostanie ukończona. Lub, wpisz stop lub t.

Polecenia debugera

W przypadku korzystania z debugera w konsoli programu PowerShell użyj następujących poleceń, aby kontrolować wykonywanie. W środowisku Windows PowerShell ISE użyj poleceń w menu Debugowanie.

Uwaga

Aby uzyskać informacje o sposobie używania debugera w innych aplikacjach hosta, zobacz dokumentację aplikacji hosta.

  • s, StepInto: wykonuje następną instrukcję, a następnie zatrzymuje.

  • v, StepOver: wykonuje następną instrukcję, ale pomija funkcje i wywołania. Pominięte instrukcje są wykonywane, ale nie są wykonywane.

  • Ctrl+Break: (Break All in ISE) Podział na uruchomiony skrypt w konsoli programu PowerShell lub Windows PowerShell ISE. Zwróć uwagę, że w programie Windows PowerShell 2.0, 3.0 i 4.0 klawisze Ctrl+Break w programie Windows PowerShell 2.0 zamyka program. Funkcja Break All działa zarówno na skryptach lokalnych, jak i zdalnych uruchamianych interaktywnie.

  • o, StepOut: Wychodzi z bieżącej funkcji; w górę o jeden poziom, jeśli jest zagnieżdżony. Jeśli w treści głównej, będzie ona kontynuowana do końca lub następnego punktu przerwania. Pominięte instrukcje są wykonywane, ale nie są wykonywane.

  • c, Continue: kontynuuje działanie do momentu ukończenia skryptu lub do momentu osiągnięcia następnego punktu przerwania. Pominięte instrukcje są wykonywane, ale nie są wykonywane.

  • l, List: wyświetla część wykonywanego skryptu. Domyślnie wyświetla bieżący wiersz, pięć poprzednich wierszy i 10 kolejnych wierszy. Aby kontynuować wyświetlanie listy skryptu, naciśnij klawisz ENTER.

  • l <m>, List: Wyświetla 16 wierszy skryptu rozpoczynających się od numeru wiersza określonego przez <m>.

  • l <m> <n>, List: wyświetla wiersze <n> skryptu rozpoczynające się od numeru wiersza określonego przez <m>.

  • q, , StopExit: zatrzymuje wykonywanie skryptu i kończy debuger. Jeśli debugujesz zadanie, uruchamiając Debug-Job polecenie cmdlet, Exit polecenie odłącza debuger i umożliwia kontynuowanie działania zadania.

  • k, Get-PsCallStack: wyświetla bieżący stos wywołań.

  • <Enter>: powtarza ostatnie polecenie, jeśli to (Step), () lub List (l).vStepOvers W przeciwnym razie reprezentuje akcję przesyłania.

  • ?, h: wyświetla pomoc polecenia debugera.

Aby zamknąć debuger, możesz użyć metody Stop (q).

Począwszy od programu PowerShell 5.0, możesz uruchomić polecenie Exit, aby zamknąć zagnieżdżona sesję debugowania uruchomioną przez uruchomienie Debug-Job polecenia lub Debug-Runspace.

Za pomocą tych poleceń debugera można uruchomić skrypt, zatrzymać się w punkcie zainteresowania, zbadać wartości zmiennych i stan systemu i kontynuować uruchamianie skryptu do momentu zidentyfikowania problemu.

Uwaga

Jeśli wejdziesz do instrukcji z operatorem przekierowania, takim jak >, kroki debugera programu PowerShell dla wszystkich pozostałych instrukcji w skrypcie.

Wyświetlanie wartości zmiennych skryptu

Podczas pracy z debugerem możesz również wprowadzić polecenia, wyświetlić wartość zmiennych, użyć poleceń cmdlet i uruchomić skrypty w wierszu polecenia. Możesz wyświetlić bieżącą wartość wszystkich zmiennych w skryptzie, który jest debugowany, z wyjątkiem następujących zmiennych automatycznych:

$_
$Args
$Input
$MyInvocation
$PSBoundParameters

Po wyświetleniu wartości dowolnej z tych zmiennych uzyskasz wartość tej zmiennej dla wewnętrznego potoku używanego przez debuger, a nie wartość zmiennej w skrypsie.

Aby wyświetlić wartość tych zmiennych dla skryptu, który jest debugowany, dodaj wiersze do skryptu, aby zapisać te wartości w nowej zmiennej. Ustaw punkt przerwania po tych nowych wierszach. Następnie można wyświetlić wartość nowej zmiennej.

Przykład:

$scriptArgs = $Args
$scriptname = $MyInvocation.PSCommandPath

Środowisko debugera

Po osiągnięciu punktu przerwania należy wprowadzić środowisko debugera. Wiersz polecenia zmienia się tak, aby rozpoczynał się od ciągu "[DBG]:". Ponadto w niektórych aplikacjach hosta, takich jak konsola programu PowerShell, zostanie otwarty zagnieżdżony monit o debugowanie. Można wykryć zagnieżdżony wiersz, powtarzając znaki większe niż (ASCII 62), które są wyświetlane w wierszu polecenia.

Aby uzyskać więcej informacji na temat dostosowywania monitu, zobacz about_Prompts.

Poziom zagnieżdżania można znaleźć przy użyciu zmiennej automatycznej $NestedPromptLevel . Zmienna automatyczna , $PSDebugContextjest zdefiniowana w zakresie lokalnym. Możesz użyć obecności zmiennej $PSDebugContext , aby określić, czy działasz w debugerze.

Na przykład:

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

Możesz użyć wartości zmiennej $PSDebugContext w debugowaniu.

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

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

Debugowanie i zakres

Włamywanie się do debugera nie zmienia zakresu, w którym działasz, ale gdy osiągniesz punkt przerwania w skrycie, przejdziesz do zakresu skryptu. Zakres skryptu jest elementem podrzędnym zakresu, w którym uruchomiono debuger.

Aby znaleźć zmienne i aliasy zdefiniowane w zakresie skryptu, użyj parametru Get-Alias Zakres poleceń cmdlet lub Get-Variable .

Na przykład następujące polecenie pobiera zmienne w zakresie lokalnego (skryptu):

Get-Variable -scope 0

Jest to przydatny sposób, aby zobaczyć tylko zmienne zdefiniowane w skry skrycie i zdefiniowane podczas debugowania.

Debugowanie w wierszu polecenia

Po ustawieniu punktu przerwania zmiennej lub punktu przerwania polecenia można ustawić punkt przerwania tylko w pliku skryptu. Jednak domyślnie punkt przerwania jest ustawiany na wszystko, co działa w bieżącej sesji.

Jeśli na przykład ustawisz punkt przerwania dla $name zmiennej, debuger przerywa działanie dowolnej zmiennej w dowolnym $name skrycie, poleceniu, funkcji, poleceniu cmdlet skryptu lub wyrażeniu, które jest uruchamiane do momentu wyłączenia lub usunięcia punktu przerwania.

Dzięki temu można debugować skrypty w bardziej realistycznym kontekście, na który mogą mieć wpływ funkcje, zmienne i inne skrypty w sesji oraz w profilu użytkownika.

Punkty przerwania wiersza są specyficzne dla plików skryptów, więc są ustawiane tylko w plikach skryptów.

Funkcje debugowania

Po ustawieniu punktu przerwania w funkcji zawierającej beginsekcje , processi end debuger przerywa działanie w pierwszym wierszu każdej sekcji.

Na przykład:

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>

Debugowanie skryptów zdalnych

Możesz uruchomić Enter-PSSession polecenie , aby uruchomić interaktywną zdalną sesję programu PowerShell, w której można ustawić punkty przerwania i debugować pliki skryptów i polecenia na komputerze zdalnym. Enter-PSSession Umożliwia ponowne połączenie rozłączonej sesji, która uruchamia skrypt lub polecenie na komputerze zdalnym. Jeśli uruchomiony skrypt osiągnie punkt przerwania, sesja klienta automatycznie uruchamia debuger. Jeśli odłączona sesja, która uruchamia skrypt, już osiągnęła punkt przerwania, Enter-PSSession automatycznie uruchamia debuger wiersza polecenia po ponownym połączeniu z sesją.

W poniższym przykładzie pokazano, jak to działa. Punkty przerwania zostały ustawione w wierszach 6, 11, 22 i 25 skryptu. Po uruchomieniu debugera istnieją dwie zmiany identyfikujące monit:

  • Nazwa komputera, na którym jest uruchomiona sesja
  • Monit grupy DBG, który informuje o tym, że jesteś w trybie debugowania
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>

Przykłady

Ten skrypt testowy wykrywa wersję programu PowerShell i wyświetla komunikat odpowiedni dla wersji. Zawiera funkcję, wywołanie funkcji i zmienną.

Następujące polecenie wyświetla zawartość pliku skryptu testowego:

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."

Aby rozpocząć, ustaw punkt przerwania w punkcie zainteresowania skryptu, taki jak wiersz, polecenie, zmienna lub funkcja.

Zacznij od utworzenia punktu przerwania wiersza w pierwszym wierszu skryptu Test.ps1 w bieżącym katalogu.

PS C:\ps-test> Set-PSBreakpoint -line 1 -script test.ps1

Polecenie zwraca obiekt 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

Teraz uruchom skrypt.

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

Gdy skrypt osiągnie pierwszy punkt przerwania, komunikat punktu przerwania wskazuje, że debuger jest aktywny. Opisuje on punkt przerwania i wyświetla podgląd pierwszego wiersza skryptu, który jest deklaracją funkcji. Wiersz polecenia również zmienia się, aby wskazać, że debuger ma kontrolę.

Wiersz podglądu zawiera nazwę skryptu i numer wiersza podglądu polecenia.

Entering debug mode. Use h or ? for help.

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

test.ps1:1   function psversion {
DBG>

Użyj polecenia Krok (s), aby wykonać pierwszą instrukcję w skrycie i wyświetlić podgląd następnej instrukcji. Następna instrukcja używa zmiennej automatycznej $MyInvocation , aby ustawić wartość $scriptName zmiennej na ścieżkę i nazwę pliku skryptu.

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

W tym momencie zmienna $scriptName nie jest wypełniana, ale można zweryfikować wartość zmiennej, wyświetlając jej wartość. W tym przypadku wartość to $null.

DBG> $scriptname
DBG>

Użyj innego Step polecenia (s), aby wykonać bieżącą instrukcję i wyświetlić podgląd następnej instrukcji w skrycie. Następna instrukcja wywołuje psversion funkcję .

DBG> s
test.ps1:12  psversion

W tym momencie zmienna $scriptName zostanie wypełniona, ale zweryfikujesz wartość zmiennej, wyświetlając jej wartość. W takim przypadku wartość jest ustawiona na ścieżkę skryptu.

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

Użyj innego polecenia Krok, aby wykonać wywołanie funkcji. Naciśnij klawisz ENTER lub wpisz "s" w polu Krok.

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

Komunikat debugowania zawiera podgląd instrukcji w funkcji. Aby wykonać tę instrukcję i wyświetlić podgląd następnej instrukcji w funkcji, możesz użyć Step polecenia . Jednak w tym przypadku użyj polecenia StepOut (o). Kończy wykonywanie funkcji (chyba że osiągnie punkt przerwania) i wykonuje kroki do następnej instrukcji w skry skrycie.

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

Ponieważ używamy ostatniej instrukcji skryptu, polecenia Krok, Krok, Krok i Kontynuuj mają taki sam efekt. W takim przypadku użyj opcji StepOut (o).

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

Polecenie StepOut wykonuje ostatnie polecenie. Standardowy wiersz polecenia wskazuje, że debuger zakończył działanie i zwrócił kontrolę do procesora poleceń.

Teraz ponownie uruchom debuger. Najpierw, aby usunąć bieżący punkt przerwania, użyj Get-PsBreakpoint poleceń cmdlet i Remove-PsBreakpoint . (Jeśli uważasz, że możesz ponownie użyć punktu przerwania, użyj Disable-PsBreakpoint polecenia cmdlet zamiast Remove-PsBreakpoint.)

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

To polecenie można skrócić jako:

PS C:\ps-test> gbp | rbp

Możesz też uruchomić polecenie, pisząc funkcję, taką jak następująca funkcja:

function delbr { gbp | rbp }

Teraz utwórz punkt przerwania w zmiennej $scriptname .

PS C:\ps-test> Set-PSBreakpoint -variable scriptname -script test.ps1

Możesz skrócić polecenie jako:

PS C:\ps-test> sbp -v scriptname -s test.ps1

Teraz uruchom skrypt. Skrypt osiąga punkt przerwania zmiennej. Tryb domyślny to Zapis, więc wykonanie zatrzymuje się tuż przed instrukcją, która zmienia wartość zmiennej.

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>

Wyświetl bieżącą wartość zmiennej $scriptName , czyli $null.

DBG> $scriptName
DBG>

Step Użyj polecenia (s), aby wykonać instrukcję, która wypełnia zmienną. Następnie wyświetl nową wartość zmiennej $scriptName .

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

Użyj polecenia krok (s), aby wyświetlić podgląd następnej instrukcji w skry skrycie.

DBG> s
test.ps1:12  psversion

Następna instrukcja to wywołanie psversion funkcji. Aby pominąć funkcję, ale nadal ją wykonać, użyj StepOver polecenia (v). Jeśli używasz StepOverfunkcji, nie jest ona skuteczna. Zostanie wyświetlone wywołanie funkcji, ale nie jest wykonywane.

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

Polecenie StepOver wykonuje funkcję i wyświetla podgląd następnej instrukcji w skry skrycie, która wyświetla końcowy wiersz.

Stop Użyj polecenia (t), aby zamknąć debuger. Wiersz polecenia powraca do standardowego wiersza polecenia.

C:\ps-test>

Aby usunąć punkty przerwania, użyj poleceń Get-PsBreakpoint cmdlet i Remove-PsBreakpoint .

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

Utwórz nowy punkt przerwania polecenia w psversion funkcji.

PS C:\ps-test> Set-PSBreakpoint -command psversion -script test.ps1

Możesz skrócić to polecenie na:

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

Teraz uruchom skrypt.

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

test.ps1:12  psversion
DBG>

Skrypt osiąga punkt przerwania w wywołaniu funkcji. W tym momencie funkcja nie została jeszcze wywołana. Dzięki temu można użyć parametru Set-PSBreakpoint Akcja w celu ustawienia warunków wykonywania punktu przerwania lub wykonywania zadań przygotowawczych lub diagnostycznych, takich jak uruchamianie dziennika lub wywoływanie skryptu diagnostycznego lub zabezpieczeń.

Aby ustawić akcję, użyj polecenia Kontynuuj (c), aby zamknąć skrypt, i Remove-PsBreakpoint polecenie, aby usunąć bieżący punkt przerwania. (Punkty przerwania są tylko do odczytu, więc nie można dodać akcji do bieżącego punktu przerwania).

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>

Teraz utwórz nowy punkt przerwania polecenia z akcją. Następujące polecenie ustawia punkt przerwania polecenia z akcją, która rejestruje wartość $scriptName zmiennej po wywołaniu funkcji. break Ponieważ słowo kluczowe nie jest używane w akcji, wykonanie nie zatrzymuje się. Backtick (`) jest znakiem kontynuacji wiersza.

PS C:\ps-test> Set-PSBreakpoint -command psversion -script test.ps1  `
-action { add-content "The value of `$scriptName is $scriptName." `
-path action.log}

Możesz również dodać akcje, które ustawiają warunki dla punktu przerwania. W poniższym poleceniu punkt przerwania polecenia jest wykonywany tylko wtedy, gdy zasady wykonywania są ustawione na RemoteSigned, najbardziej restrykcyjne zasady, które nadal zezwalają na uruchamianie skryptów.

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

Słowo break kluczowe w akcji kieruje debuger do wykonania punktu przerwania. Możesz również użyć słowa kluczowego continue , aby skierować debuger do wykonania bez przerywania. Ponieważ domyślnym słowem kluczowym jest continue, należy określić break , aby zatrzymać wykonywanie.

Teraz uruchom skrypt.

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

test.ps1:12  psversion

Ponieważ zasady wykonywania są ustawione na RemoteSigned, wykonanie zatrzymuje się na wywołaniu funkcji.

Na tym etapie warto sprawdzić stos wywołań. Get-PsCallStack Użyj polecenia cmdlet lub Get-PsCallStack polecenia debugera (k). Następujące polecenie pobiera bieżący stos wywołań.

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

W tym przykładzie pokazano tylko kilka sposobów używania debugera programu PowerShell.

Inne funkcje debugowania w programie PowerShell

Oprócz debugera programu PowerShell program PowerShell zawiera kilka innych funkcji, których można użyć do debugowania skryptów i funkcji.

  • Polecenie Set-PSDebug cmdlet oferuje bardzo podstawowe funkcje debugowania skryptów, w tym kroki i śledzenie.

  • Set-StrictMode Użyj polecenia cmdlet , aby wykryć odwołania do niezainicjowanych zmiennych, aby odwoływać się do nieistniejących właściwości obiektu i składni funkcji, która nie jest prawidłowa.

  • Dodaj instrukcje diagnostyczne do skryptu, takie jak instrukcje, które wyświetlają wartość zmiennych, instrukcje odczytujące dane wejściowe z wiersza polecenia lub instrukcje raportujące bieżącą instrukcję. Użyj poleceń cmdlet zawierających czasownik Write dla tego zadania, takie jak Write-Host, Write-Debug, Write-Warningi Write-Verbose.

Zobacz też