about_Debuggers

Krátký popis

Popisuje ladicí program PowerShellu.

Dlouhý popis

Ladění je proces zkoumání skriptu, když je spuštěný, aby identifikoval a opravil chyby v pokynech ke skriptu. Ladicí program PowerShellu vám může pomoct prozkoumat a identifikovat chyby a neektivosti ve vašich skriptech, funkcích, příkazech, konfiguracích DSC (Desired State Configuration) PowerShellu nebo výrazech.

Od PowerShellu 5.0 se ladicí program PowerShellu aktualizoval na ladicí skripty, funkce, příkazy, konfigurace nebo výrazy spuštěné v konzole nebo integrovaném skriptovacím prostředí Windows PowerShellu (ISE) na vzdálených počítačích.

Poznámka:

Prostředí Windows PowerShell ISE podporuje jenom Windows PowerShell. Pro PowerShell 6 a vyšší musíte použít Visual Studio Code s rozšířením pro PowerShell. Další informace naleznete v tématu Ladění pomocí editoru Visual Studio Code.

Rutiny ladicího programu

Ladicí program PowerShellu obsahuje následující sadu rutin:

  • Set-PSBreakpoint: Nastaví zarážky na řádcích, proměnných a příkazech.
  • Get-PSBreakpoint: Získá zarážky v aktuální relaci.
  • Disable-PSBreakpoint: Vypne zarážky v aktuální relaci.
  • Enable-PSBreakpoint: Znovu povolí zarážky v aktuální relaci.
  • Remove-PSBreakpoint: Odstraní zarážky z aktuální relace.
  • Get-PSCallStack: Zobrazí aktuální zásobník volání.

Spuštění a zastavení ladicího programu

Pokud chcete spustit ladicí program, nastavte jednu nebo více zarážek a pak spusťte skript, příkaz nebo funkci, kterou chcete ladit.

Když dosáhnete zarážky, spuštění se zastaví a ovládací prvek se převrátí do ladicího programu.

Pokud chcete ladicí program zastavit, spusťte skript, příkaz nebo funkci, dokud se nedokončí. Nebo zadejte stop nebo t.

Příkazy ladicího programu

Při použití ladicího programu v konzole PowerShellu použijte následující příkazy k řízení provádění. V prostředí Windows PowerShell ISE použijte příkazy v nabídce Ladění.

Poznámka:

Informace o tom, jak používat ladicí program v jiných hostitelských aplikacích, najdete v dokumentaci k hostitelské aplikaci.

  • s, StepInto: Provede další příkaz a pak se zastaví.

  • v, StepOver: Provede další příkaz, ale přeskočí funkce a vyvolání. Přeskočené příkazy se spustí, ale neprojdou.

  • Ctrl+Break: (Break All in ISE) Rozdělí do spuštěného skriptu v konzole PowerShellu nebo prostředí Windows PowerShell ISE. Všimněte si, že kombinace kláves Ctrl+Break v prostředí Windows PowerShell 2.0, 3.0 a 4.0 program zavře. Break All funguje na místních i vzdálených interaktivně spuštěných skriptech.

  • o, StepOut: Kroky mimo aktuální funkci; o jednu úroveň výš, pokud je vnořená. Pokud je v hlavním těle, pokračuje na konec nebo další zarážku. Přeskočené příkazy se spustí, ale neprojdou.

  • c, Continue: Pokračuje ve spuštění, dokud se skript nedokončí nebo dokud nedosáhne další zarážky. Přeskočené příkazy se spustí, ale neprojdou.

  • l, List: Zobrazí část skriptu, který se spouští. Ve výchozím nastavení zobrazuje aktuální řádek, pět předchozích řádků a 10 dalších řádků. Pokud chcete pokračovat v výpisu skriptu, stiskněte enter.

  • l <m>, List: Zobrazí 16 řádků skriptu začínajícího číslem řádku určeným parametrem <m>.

  • l <m> <n>, List: Zobrazí <n> řádky skriptu, počínaje číslem řádku určeným <m>.

  • q, , StopExit: Zastaví spuštění skriptu a ukončí ladicí program. Pokud ladíte úlohu spuštěním Debug-Job rutiny, Exit příkaz odpojí ladicí program a umožní úlohu pokračovat ve spuštění.

  • k, Get-PsCallStack: Zobrazí aktuální zásobník volání.

  • <Enter>: Zopakuje poslední příkaz, pokud byl Step (s), StepOver (v) nebo List (l). V opačném případě představuje akci odeslání.

  • ?, h: Zobrazí nápovědu k příkazu ladicího programu.

K ukončení ladicího programu můžete použít Stop (q).

Počínaje PowerShellem 5.0 můžete spuštěním příkazu Exit ukončit vnořenou ladicí relaci, kterou jste spustili spuštěním příkazu nebo Debug-JobDebug-Runspace.

Pomocí těchto příkazů ladicího programu můžete spustit skript, zastavit na místě zájmu, prozkoumat hodnoty proměnných a stav systému a pokračovat ve spuštění skriptu, dokud neidenticialujete problém.

Poznámka:

Pokud přejdete do příkazu s operátorem přesměrování, jako >je například , provedete kroky ladicího programu PowerShellu nad všemi zbývajícími příkazy ve skriptu.

Zobrazení hodnot proměnných skriptu

V ladicím programu můžete také zadat příkazy, zobrazit hodnotu proměnných, používat rutiny a spouštět skripty na příkazovém řádku. Aktuální hodnotu všech proměnných můžete zobrazit ve skriptu, který je laděný, s výjimkou následujících automatických proměnných:

$_
$Args
$Input
$MyInvocation
$PSBoundParameters

Když zobrazíte hodnotu kterékoli z těchto proměnných, získáte hodnotu této proměnné pro interní kanál, který ladicí program používá, nikoli hodnotu proměnné ve skriptu.

Pokud chcete zobrazit hodnotu těchto proměnných pro skript, který je laděný, přidejte do skriptu řádky pro uložení těchto hodnot do nové proměnné. Nastavte zarážku za těmito novými řádky. Pak můžete zobrazit hodnotu nové proměnné.

Příklad:

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

Prostředí ladicího programu

Když dosáhnete zarážky, zadáte prostředí ladicího programu. Příkazový řádek se změní tak, aby začal na "[DBG]:". V některých hostitelských aplikacích, jako je například konzola PowerShellu, se otevře vnořená výzva k ladění. Vnořenou výzvu můžete zjistit opakováním znaků větších než (ASCII 62), které se zobrazí na příkazovém řádku.

Další informace o přizpůsobení výzvy najdete v tématu about_Prompts.

Úroveň vnoření najdete pomocí $NestedPromptLevel automatické proměnné. Automatická proměnná $PSDebugContextje definována v místním oboru. Přítomnost proměnné můžete použít k určení, $PSDebugContext jestli spouštíte v rámci ladicího programu.

Příklad:

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

V ladění můžete použít hodnotu $PSDebugContext proměnné.

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

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

Ladění a obor

Rozdělení do ladicího programu nezmění obor, ve kterém pracujete, ale když ve skriptu dosáhnete zarážky, přesunete se do oboru skriptu. Obor skriptu je podřízený obor, ve kterém jste spustili ladicí program.

K vyhledání proměnných a aliasů definovaných v oboru skriptu použijte parametr Scope pro Get-Alias rutiny.Get-Variable

Například následující příkaz získá proměnné v oboru místního (skriptu):

Get-Variable -scope 0

To je užitečný způsob, jak zobrazit pouze proměnné, které jste definovali ve skriptu a které jste definovali při ladění.

Ladění na příkazovém řádku

Když nastavíte zarážku proměnné nebo zarážku příkazu, můžete zarážku nastavit pouze v souboru skriptu. Ve výchozím nastavení je ale zarážka nastavená na cokoli, co se spouští v aktuální relaci.

Pokud například nastavíte zarážku na $name proměnnou, ladicí program se přeruší u jakékoli proměnné v libovolném $name skriptu, příkazu, funkci, rutině skriptu nebo výrazu, který spustíte, dokud nezakážete nebo neodeberete zarážku.

To vám umožní ladit skripty v realističtějším kontextu, ve kterém mohou být ovlivněny funkcemi, proměnnými a dalšími skripty v relaci a v profilu uživatele.

Zarážky řádků jsou specifické pro soubory skriptu, takže jsou nastavené jenom v souborech skriptů.

Ladění funkcí

Když nastavíte zarážku na funkci, která obsahuje beginprocessoddíly a end oddíly, ladicí program se přeruší na prvním řádku každého oddílu.

Příklad:

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>

Ladění vzdálených skriptů

Můžete spustit Enter-PSSession interaktivní vzdálenou relaci PowerShellu, ve které můžete nastavit zarážky a ladit soubory a příkazy skriptu na vzdáleném počítači. Enter-PSSession umožňuje znovu připojit odpojenou relaci, na které běží skript nebo příkaz ve vzdáleném počítači. Pokud spuštěný skript dosáhne zarážky, relace klienta automaticky spustí ladicí program. Pokud odpojená relace, na které běží skript, už narazila na zarážku, Enter-PSSession automaticky spustí ladicí program příkazového řádku při opětovném připojení k relaci.

Následující příklad ukazuje, jak to funguje. Zarážky byly nastaveny na řádky 6, 11, 22 a 25 skriptu. Při spuštění ladicího programu existují dvě identifikovatelné změny výzvy:

  • Název počítače, na kterém je relace spuštěná
  • Výzva dbg, která vás informuje o tom, že jste v režimu ladění
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>

Příklady

Tento testovací skript rozpozná verzi PowerShellu a zobrazí zprávu odpovídající verzi. Zahrnuje funkci, volání funkce a proměnnou.

Následující příkaz zobrazí obsah souboru testovacího skriptu:

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

Začněte tím, že nastavíte zarážku v okamžiku zájmu ve skriptu, například řádek, příkaz, proměnnou nebo funkci.

Začněte vytvořením zarážky řádku na prvním řádku skriptu Test.ps1 v aktuálním adresáři.

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

Příkaz vrátí objekt 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

Teď spusťte skript.

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

Když skript dosáhne první zarážky, zpráva zarážky indikuje, že ladicí program je aktivní. Popisuje zarážku a zobrazí náhled prvního řádku skriptu, což je deklarace funkce. Příkazový řádek se také změní, aby indikoval, že ladicí program má ovládací prvek.

Řádek náhledu obsahuje název skriptu a číslo řádku náhledu příkazu.

Entering debug mode. Use h or ? for help.

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

test.ps1:1   function psversion {
DBG>

Pomocí příkazu Step (s) spusťte první příkaz ve skriptu a zobrazte náhled dalšího příkazu. Další příkaz použije automatickou $MyInvocation proměnnou k nastavení hodnoty $scriptName proměnné na cestu a název souboru skriptu.

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

V tomto okamžiku $scriptName není proměnná naplněna, ale hodnotu proměnné můžete ověřit zobrazením její hodnoty. V tomto případě je $nullhodnota .

DBG> $scriptname
DBG>

Pomocí jiného Step příkazu (s) spusťte aktuální příkaz a zobrazte náhled dalšího příkazu ve skriptu. Další příkaz volá psversion funkci.

DBG> s
test.ps1:12  psversion

V tomto okamžiku $scriptName se proměnná naplní, ale hodnotu proměnné ověříte zobrazením její hodnoty. V tomto případě je hodnota nastavena na cestu skriptu.

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

K provedení volání funkce použijte jiný příkaz Krok. Stiskněte ENTER nebo zadejte "s" pro krok.

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

Ladicí zpráva obsahuje náhled příkazu ve funkci. Pokud chcete tento příkaz spustit a zobrazit náhled dalšího příkazu ve funkci, můžete použít Step příkaz. V tomto případě ale použijte příkaz StepOut (o). Dokončí provádění funkce (pokud nedosáhne zarážky) a kroky k dalšímu příkazu ve skriptu.

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

Vzhledem k tomu, že jsme na posledním příkazu ve skriptu, mají příkazy Step, StepOut a Continue stejný účinek. V tomto případě použijte StepOut (o).

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

Příkaz StepOut spustí poslední příkaz. Standardní příkazový řádek označuje, že ladicí program ukončil a vrátil ovládací prvek do procesoru příkazů.

Teď znovu spusťte ladicí program. Nejprve odstraňte aktuální zarážku pomocí rutin Get-PsBreakpoint a Remove-PsBreakpoint rutin. (Pokud si myslíte, že byste mohli zarážku znovu použít, použijte místo této rutiny Disable-PsBreakpointRemove-PsBreakpoint.)

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

Tento příkaz můžete zkrátit takto:

PS C:\ps-test> gbp | rbp

Nebo spusťte příkaz napsáním funkce, například následující funkce:

function delbr { gbp | rbp }

Teď vytvořte zarážku v $scriptname proměnné.

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

Příkaz můžete zkrátit takto:

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

Teď spusťte skript. Skript dosáhne zarážky proměnné. Výchozí režim je Write, takže provádění se zastaví těsně před příkazem, který změní hodnotu proměnné.

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>

Zobrazí aktuální hodnotu $scriptName proměnné, což je $null.

DBG> $scriptName
DBG>

Step Pomocí příkazu (s) spusťte příkaz, který naplní proměnnou. Pak zobrazte novou hodnotu $scriptName proměnné.

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

Pomocí příkazu Step (s) zobrazte náhled dalšího příkazu ve skriptu.

DBG> s
test.ps1:12  psversion

Dalším příkazem je volání psversion funkce. Pokud chcete funkci přeskočit, ale přesto ji spustit, použijte StepOver příkaz (v). Pokud už funkci používáte StepOver, není efektivní. Zobrazí se volání funkce, ale nespustí se.

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

Příkaz StepOver spustí funkci a zobrazí náhled dalšího příkazu ve skriptu, který vytiskne poslední řádek.

Stop Pomocí příkazu (t) ukončete ladicí program. Příkazový řádek se vrátí na standardní příkazový řádek.

C:\ps-test>

Pokud chcete odstranit zarážky, použijte rutinyGet-PsBreakpoint.Remove-PsBreakpoint

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

Vytvořte pro funkci novou zarážku psversion příkazu.

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

Tento příkaz můžete zkrátit na:

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

Teď spusťte skript.

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

test.ps1:12  psversion
DBG>

Skript dosáhne zarážky při volání funkce. V tuto chvíli se funkce ještě nevolala. To vám umožní použít parametr Set-PSBreakpoint akce k nastavení podmínek pro spuštění zarážky nebo k provádění přípravných nebo diagnostických úloh, jako je spuštění protokolu nebo vyvolání diagnostického nebo bezpečnostního skriptu.

Pokud chcete nastavit akci, pomocí příkazu Pokračovat (c) ukončete skript a Remove-PsBreakpoint příkaz k odstranění aktuální zarážky. (Zarážky jsou jen pro čtení, takže do aktuální zarážky nemůžete přidat akci.)

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>

Teď vytvořte novou zarážku příkazu pomocí akce. Následující příkaz nastaví zarážku příkazu s akcí, která zaznamená hodnotu $scriptName proměnné při zavolání funkce. Vzhledem k tomu, že se break klíčové slovo v akci nepoužívá, provádění se nezastaví. Backtick (`) je znak pokračování řádku.

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

Můžete také přidat akce, které nastaví podmínky pro zarážku. V následujícím příkazu se zarážka příkazu spustí pouze v případě, že je zásada spouštění nastavena na RemoteSigned, nejvíce omezující zásady, které vám stále umožňují spouštět skripty.

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

Klíčové break slovo v akci směruje ladicí program tak, aby spustil zarážku. Pomocí klíčového continue slova můžete také nasměrovat ladicí program tak, aby se spustil bez přerušení. Vzhledem k tomu, že výchozí klíčové slovo je continue, je nutné zadat break , aby se zastavilo provádění.

Teď spusťte skript.

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

test.ps1:12  psversion

Vzhledem k tomu, že je zásada spouštění nastavena na RemoteSigned, provádění se zastaví při volání funkce.

V tuto chvíli můžete chtít zkontrolovat zásobník volání. Použijte rutinu Get-PsCallStackGet-PsCallStack nebo příkaz ladicího programu (k). Následující příkaz získá aktuální zásobník volání.

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

Tento příklad ukazuje jen několik z mnoha způsobů použití ladicího programu PowerShellu.

Další funkce ladění v PowerShellu

Kromě ladicího programu PowerShellu obsahuje PowerShell několik dalších funkcí, které můžete použít k ladění skriptů a funkcí.

  • Rutina Set-PSDebug nabízí velmi základní funkce ladění skriptů, včetně krokování a trasování.

  • Pomocí rutiny Set-StrictMode můžete detekovat odkazy na neinicializované proměnné, odkazy na neexistující vlastnosti objektu a syntaxi funkce, která není platná.

  • Přidejte do skriptu diagnostické příkazy, například příkazy, které zobrazují hodnotu proměnných, příkazy, které čtou vstup z příkazového řádku, nebo příkazy, které hlásí aktuální instrukce. Použijte rutiny, které obsahují příkaz Write pro tento úkol, například Write-Host, Write-Debug, Write-Warninga Write-Verbose.

Viz také