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
, ,Stop
Exit
: Zastaví spuštění skriptu a ukončí ladicí program. Pokud ladíte úlohu spuštěnímDebug-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 bylStep
(s
),StepOver
(v
) neboList
(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-Job
Debug-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á $PSDebugContext
je 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 begin
process
oddí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 $null
hodnota .
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-PsBreakpoint
Remove-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-PsCallStack
Get-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-Warning
aWrite-Verbose
.