Udostępnij za pośrednictwem


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.

Nuta

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. Możesz też wpisać 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.

Nuta

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) Dzieli się na uruchomiony skrypt w konsoli programu PowerShell lub Windows PowerShell ISE. Należy pamiętać, że ctrl+Break w programie Windows PowerShell 2.0, 3.0 i 4.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, dopóki skrypt nie zostanie ukończony 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 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 <n> wiersze skryptu, począwszy od numeru wiersza określonego przez <m>.

  • q, Stop, Exit: zatrzymuje wykonywanie skryptu i zamyka debuger. Jeśli debugujesz zadanie, uruchamiając polecenie cmdlet Debug-Job, polecenie Exit 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 zostało Step (s), StepOver (v) lub List (l). W przeciwnym razie reprezentuje akcję przesyłania.

  • ?, h: Wyświetla Pomoc polecenia debugera.

Aby zamknąć debuger, możesz użyć 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 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.

Nuta

W przypadku przechodzenia do instrukcji za pomocą operatora przekierowania, takiego jak >, debuger programu PowerShell przechodzi przez wszystkie pozostałe instrukcje 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.

Na 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 $NestedPromptLevel zmiennej automatycznej. Zmienna automatyczna, $PSDebugContext, jest 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 Zakres poleceń cmdlet Get-Alias 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 w zmiennej $name, debuger przerywa działanie dowolnej zmiennej $name w dowolnym skry skrycie, poleceniu, funkcji, poleceniu cmdlet lub wyrażeniu skryptu, 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, która ma begin, processi end sekcjach, 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, aby uruchomić interaktywną sesję zdalnego 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, w której jest uruchomiony skrypt, osiągnęła już 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ść zmiennej $scriptName na ścieżkę i nazwę pliku skryptu.

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

Na tym etapie 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 polecenia Step (s), aby wykonać bieżącą instrukcję i wyświetlić podgląd następnej instrukcji w skry skrycie. Następna instrukcja wywołuje funkcję psversion.

DBG> s
test.ps1:12  psversion

W tym momencie zmienna $scriptName zostanie wypełniona, ale zweryfikujesz wartość zmiennej. 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 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ć polecenia Step. 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 poleceń cmdlet Get-PSBreakpoint i Remove-PSBreakpoint. (Jeśli uważasz, że możesz ponownie użyć punktu przerwania, użyj polecenia cmdlet Disable-PSBreakpoint 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, która jest $null.

DBG> $scriptName
DBG>

Użyj polecenia Step (s), aby wykonać instrukcję wypełniającą 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 funkcji psversion. Aby pominąć funkcję, ale nadal ją wykonać, użyj polecenia StepOver (v). Jeśli jesteś już w funkcji, gdy używasz StepOver, nie jest to skuteczne. 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.

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

C:\ps-test>

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

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

Utwórz nowy punkt przerwania polecenia w funkcji psversion.

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. Daje to możliwość użycia parametru Action Set-PSBreakpoint 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 zakończyć działanie skryptu, a polecenie Remove-PSBreakpoint, 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ść zmiennej $scriptName po wywołaniu funkcji. Ponieważ słowo kluczowe break 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 kluczowe break 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ślne słowo kluczowe to 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ń. Użyj polecenia cmdlet Get-PSCallStack lub polecenia debugera Get-PSCallStack (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 cmdlet Set-PSDebug oferuje bardzo podstawowe funkcje debugowania skryptów, w tym kroki i śledzenie.

  • Użyj polecenia cmdlet Set-StrictMode, aby wykryć odwołania do niezainicjowanych zmiennych, odwołań do nieistniejących właściwości obiektu oraz 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, takich jak Write-Host, Write-Debug, Write-Warningi Write-Verbose.

Zobacz także