about_Debuggers
Descrizione breve
Descrive il debugger di PowerShell.
Descrizione lunga
Il debug è il processo di analisi di uno script durante l'esecuzione per identificare e correggere gli errori nelle istruzioni dello script. Il debugger di PowerShell consente di esaminare e identificare errori e inefficienze negli script, nelle funzioni, nei comandi, nelle configurazioni DSC (Desired State Configuration) di PowerShell o nelle espressioni.
A partire da PowerShell 5.0, il debugger di PowerShell è stato aggiornato per eseguire il debug di script, funzioni, comandi, configurazioni o espressioni in esecuzione nella console o in Windows PowerShell Integrated Scripting Environment (ISE) nei computer remoti.
Nota
Windows PowerShell ISE supporta solo Windows PowerShell. Per PowerShell 6 e versioni successive è necessario usare Visual Studio Code con l'estensione per PowerShell. Per altre informazioni, vedere Debug con Visual Studio Code.
Cmdlet del debugger
Il debugger di PowerShell include il set di cmdlet seguente:
Set-PSBreakpoint
: imposta punti di interruzione su righe, variabili e comandi.Get-PSBreakpoint
: ottiene i punti di interruzione nella sessione corrente.Disable-PSBreakpoint
: disattiva i punti di interruzione nella sessione corrente.Enable-PSBreakpoint
: abilita nuovamente i punti di interruzione nella sessione corrente.Remove-PSBreakpoint
: elimina i punti di interruzione dalla sessione corrente.Get-PSCallStack
: visualizza lo stack di chiamate corrente.
Avvio e arresto del debugger
Per avviare il debugger, impostare uno o più punti di interruzione, quindi eseguire lo script, il comando o la funzione di cui si vuole eseguire il debug.
Quando si raggiunge un punto di interruzione, l'esecuzione viene arrestata e il controllo viene trasformato nel debugger.
Per arrestare il debugger, eseguire lo script, il comando o la funzione fino al completamento.
In alternativa, digitare stop
o t
.
Comandi del debugger
Quando si usa il debugger nella console di PowerShell, usare i comandi seguenti per controllare l'esecuzione. In Windows PowerShell ISE usare i comandi nel menu Debug.
Nota
Per informazioni su come usare il debugger in altre applicazioni host, vedere la documentazione dell'applicazione host.
s
,StepInto
: esegue l'istruzione successiva e quindi si arresta.v
,StepOver
: esegue l'istruzione successiva, ma ignora le funzioni e le chiamate. Le istruzioni ignorate vengono eseguite, ma non una alla volta.Ctrl+Break
: (Interrompi tutto in ISE) Suddivide in uno script in esecuzione all'interno della console di PowerShell o in Windows PowerShell ISE. Si noti che CTRL+Interrompi in Windows PowerShell 2.0, 3.0 e 4.0 chiude il programma. Interrompi tutto funziona sia su script locali che remoti in esecuzione interattiva.o
,StepOut
: esce dalla funzione corrente; fino a un livello se annidato. Se nel corpo principale continua fino alla fine o al punto di interruzione successivo. Le istruzioni ignorate vengono eseguite, ma non una alla volta.c
,Continue
: continua l'esecuzione fino al completamento dello script o fino al raggiungimento del punto di interruzione successivo. Le istruzioni ignorate vengono eseguite, ma non una alla volta.l
,List
: visualizza la parte dello script in esecuzione. Per impostazione predefinita, visualizza la riga corrente, cinque righe precedenti e 10 righe successive. Per continuare a elencare lo script, premere INVIO.l <m>
,List
: visualizza 16 righe dello script che iniziano con il numero di riga specificato da<m>
.l <m> <n>
,List
: visualizza<n>
le righe dello script, a partire dal numero di riga specificato da<m>
.q
,Stop
, ,Exit
: arresta l'esecuzione dello script ed esce dal debugger. Se si esegue il debug di un processo eseguendo ilDebug-Job
cmdlet , ilExit
comando scollega il debugger e consente al processo di continuare l'esecuzione.k
,Get-PsCallStack
: visualizza lo stack di chiamate corrente.<Enter>
: ripete l'ultimo comando se èStep
(s
),StepOver
(v
) oList
(l
). In caso contrario, rappresenta un'azione di invio.?
,h
: visualizza la Guida del comando del debugger.
Per uscire dal debugger, è possibile usare Stop
(q
).
A partire da PowerShell 5.0, è possibile eseguire il comando Exit per uscire da una sessione di debug annidata avviata eseguendo Debug-Job
o Debug-Runspace
.
Usando questi comandi del debugger, è possibile eseguire uno script, arrestarsi in un punto di preoccupazione, esaminare i valori delle variabili e lo stato del sistema e continuare a eseguire lo script fino a quando non è stato identificato un problema.
Nota
Se si esegue un'istruzione con un operatore di reindirizzamento, ad esempio >
, il debugger di PowerShell esegue i passaggi per tutte le istruzioni rimanenti nello script.
Visualizzazione dei valori delle variabili di script
Mentre si è nel debugger, è anche possibile immettere i comandi, visualizzare il valore delle variabili, usare i cmdlet ed eseguire script nella riga di comando. È possibile visualizzare il valore corrente di tutte le variabili nello script di cui è in corso il debug, ad eccezione delle variabili automatiche seguenti:
$_
$Args
$Input
$MyInvocation
$PSBoundParameters
Quando si visualizza il valore di una di queste variabili, si ottiene il valore di tale variabile per una pipeline interna usata dal debugger, non il valore della variabile nello script.
Per visualizzare il valore di queste variabili per lo script di cui è in corso il debug, aggiungere righe allo script per salvare questi valori in una nuova variabile. Impostare il punto di interruzione dopo queste nuove righe. È quindi possibile visualizzare il valore della nuova variabile.
ad esempio:
$scriptArgs = $Args
$scriptname = $MyInvocation.PSCommandPath
Ambiente del debugger
Quando si raggiunge un punto di interruzione, immettere l'ambiente del debugger. Il prompt dei comandi cambia in modo che inizi con "[DBG]:". In alcune applicazioni host, ad esempio la console di PowerShell, viene aperto un prompt annidato per il debug. È possibile rilevare il prompt annidato ripetendo caratteri maggiori di (ASCII 62) visualizzati al prompt dei comandi.
Per altre informazioni sulla personalizzazione del prompt, vedere about_Prompts.
È possibile trovare il livello di annidamento usando la $NestedPromptLevel
variabile automatica. La variabile automatica, $PSDebugContext
, è definita nell'ambito locale. È possibile usare la presenza della $PSDebugContext
variabile per determinare se si esegue all'interno del debugger.
Ad esempio:
if ($PSDebugContext) {"Debugging"} else {"Not Debugging"}
È possibile usare il valore della $PSDebugContext
variabile nel debug.
[DBG]: PS>>> $PSDebugContext.InvocationInfo
Name CommandLineParameters UnboundArguments Location
---- --------------------- ---------------- --------
= {} {} C:\ps-test\vote.ps1 (1)
Debug e ambito
L'interruzione nel debugger non modifica l'ambito in cui si sta operando, ma quando si raggiunge un punto di interruzione in uno script, si passa all'ambito dello script. L'ambito dello script è un elemento figlio dell'ambito in cui è stato eseguito il debugger.
Per trovare le variabili e gli alias definiti nell'ambito dello script, usare il parametro Scope dei Get-Alias
cmdlet o Get-Variable
.
Ad esempio, il comando seguente ottiene le variabili nell'ambito locale (script):
Get-Variable -scope 0
Si tratta di un modo utile per visualizzare solo le variabili definite nello script e definite durante il debug.
Debug nella riga di comando
Quando si imposta un punto di interruzione di variabile o un punto di interruzione del comando, è possibile impostare il punto di interruzione solo in un file di script. Tuttavia, per impostazione predefinita, il punto di interruzione viene impostato su qualsiasi elemento eseguito nella sessione corrente.
Ad esempio, se si imposta un punto di interruzione sulla $name
variabile, il debugger si interrompe su qualsiasi $name
variabile in qualsiasi script, comando, funzione, cmdlet script o espressione eseguita fino a quando non si disabilita o si rimuove il punto di interruzione.
In questo modo è possibile eseguire il debug degli script in un contesto più realistico in cui potrebbero essere influenzati da funzioni, variabili e altri script nella sessione e nel profilo dell'utente.
I punti di interruzione di riga sono specifici dei file di script, quindi vengono impostati solo nei file di script.
Funzioni di debug
Quando si imposta un punto di interruzione su una funzione con begin
sezioni , process
e end
, il debugger si interrompe alla prima riga di ogni sezione.
Ad esempio:
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>
Debug di script remoti
È possibile eseguire Enter-PSSession
per avviare una sessione remota interattiva di PowerShell in cui è possibile impostare punti di interruzione e eseguire il debug di file di script e comandi nel computer remoto. Enter-PSSession
consente di riconnettere una sessione disconnessa che esegue uno script o un comando in un computer remoto. Se lo script in esecuzione raggiunge un punto di interruzione, la sessione client avvia automaticamente il debugger. Se la sessione disconnessa che esegue uno script ha già raggiunto un punto di interruzione, Enter-PSSession
avvia automaticamente il debugger della riga di comando quando si riconnette alla sessione.
Nell'esempio seguente viene illustrato come funziona. I punti di interruzione sono stati impostati alle righe 6, 11, 22 e 25 dello script. All'avvio del debugger sono presenti due modifiche che identificano il prompt:
- Nome del computer in cui è in esecuzione la sessione
- Richiesta dbg che consente di sapere di essere in modalità di debug
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>
Esempi
Questo script di test rileva la versione di PowerShell e visualizza un messaggio appropriato per la versione. Include una funzione, una chiamata di funzione e una variabile.
Il comando seguente visualizza il contenuto del file di script di test:
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."
Per iniziare, impostare un punto di interruzione a un punto di interesse per lo script, ad esempio una riga, un comando, una variabile o una funzione.
Per iniziare, creare un punto di interruzione di riga nella prima riga dello script Test.ps1 nella directory corrente.
PS C:\ps-test> Set-PSBreakpoint -line 1 -script test.ps1
Il comando restituisce un oggetto 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
A questo punto, avviare lo script.
PS C:\ps-test> .\test.ps1
Quando lo script raggiunge il primo punto di interruzione, il messaggio del punto di interruzione indica che il debugger è attivo. Descrive il punto di interruzione e visualizza in anteprima la prima riga dello script, ovvero una dichiarazione di funzione. Il prompt dei comandi cambia anche per indicare che il debugger dispone del controllo .
La riga di anteprima include il nome dello script e il numero di riga del comando visualizzato in anteprima.
Entering debug mode. Use h or ? for help.
Hit Line breakpoint on 'C:\ps-test\test.ps1:1'
test.ps1:1 function psversion {
DBG>
Usare il comando Step (s) per eseguire la prima istruzione nello script e per visualizzare in anteprima l'istruzione successiva. L'istruzione successiva usa la $MyInvocation
variabile automatica per impostare il valore della $scriptName
variabile sul percorso e sul nome file del file di script.
DBG> s
test.ps1:11 $scriptName = $MyInvocation.PSCommandPath
A questo punto, la $scriptName
variabile non viene popolata, ma è possibile verificare il valore della variabile visualizzandone il valore. In questo caso il valore è $null
.
DBG> $scriptname
DBG>
Usare un altro Step
comando (s
) per eseguire l'istruzione corrente e visualizzare in anteprima l'istruzione successiva nello script. L'istruzione successiva chiama la psversion
funzione .
DBG> s
test.ps1:12 psversion
A questo punto, la $scriptName
variabile viene popolata, ma si verifica il valore della variabile visualizzandone il valore. In questo caso, il valore viene impostato sul percorso dello script.
DBG> $scriptName
C:\ps-test\test.ps1
Usare un altro comando Step per eseguire la chiamata di funzione. Premere INVIO oppure digitare "s" per Passaggio.
DBG> s
test.ps1:2 "PowerShell " + $PSVersionTable.PSVersion
Il messaggio di debug include un'anteprima dell'istruzione nella funzione . Per eseguire questa istruzione e per visualizzare in anteprima l'istruzione successiva nella funzione, è possibile usare un Step
comando . In questo caso, tuttavia, usare un comando StepOut (o). Completa l'esecuzione della funzione (a meno che non raggiunga un punto di interruzione) e passi all'istruzione successiva nello script.
DBG> o
Windows PowerShell 2.0
Have you run a background job today (start-job)?
test.ps1:13 "Done $scriptName"
Poiché si usa l'ultima istruzione nello script, i comandi Step, StepOut e Continue hanno lo stesso effetto. In questo caso, usare StepOut (o).
Done C:\ps-test\test.ps1
PS C:\ps-test>
Il comando StepOut esegue l'ultimo comando. Il prompt dei comandi standard indica che il debugger ha chiuso e restituito il controllo al processore di comandi.
Eseguire di nuovo il debugger. Prima di tutto, per eliminare il punto di interruzione corrente, usare i Get-PsBreakpoint
cmdlet e Remove-PsBreakpoint
. Se si ritiene di riutilizzare il punto di Remove-PsBreakpoint
interruzione, usare il Disable-PsBreakpoint
cmdlet anziché .)
PS C:\ps-test> Get-PSBreakpoint| Remove-PSBreakpoint
È possibile abbreviare il comando in
PS C:\ps-test> gbp | rbp
In alternativa, eseguire il comando scrivendo una funzione, ad esempio la funzione seguente:
function delbr { gbp | rbp }
Creare ora un punto di interruzione nella $scriptname
variabile.
PS C:\ps-test> Set-PSBreakpoint -variable scriptname -script test.ps1
È possibile abbreviare il comando come segue:
PS C:\ps-test> sbp -v scriptname -s test.ps1
A questo punto, avviare lo script. Lo script raggiunge il punto di interruzione della variabile. La modalità predefinita è Write, quindi l'esecuzione si arresta immediatamente prima dell'istruzione che modifica il valore della variabile.
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>
Visualizzare il valore corrente della $scriptName
variabile , ovvero $null
.
DBG> $scriptName
DBG>
Usare un Step
comando (s
) per eseguire l'istruzione che popola la variabile. Visualizzare quindi il nuovo valore della $scriptName
variabile.
DBG> $scriptName
C:\ps-test\test.ps1
Usare un comando Step (s) per visualizzare in anteprima l'istruzione successiva nello script.
DBG> s
test.ps1:12 psversion
L'istruzione successiva è una chiamata alla psversion
funzione . Per ignorare la funzione ma comunque eseguirla, usare un StepOver
comando (v
). Se si è già nella funzione quando si usa StepOver
, non è efficace. Viene visualizzata la chiamata di funzione, ma non viene eseguita.
DBG> v
Windows PowerShell 2.0
Have you run a background job today (start-job)?
test.ps1:13 "Done $scriptName"
Il StepOver
comando esegue la funzione e visualizza l'anteprima dell'istruzione successiva nello script, che stampa la riga finale.
Usare un Stop
comando (t
) per uscire dal debugger. Il prompt dei comandi ripristina il prompt dei comandi standard.
C:\ps-test>
Per eliminare i punti di interruzione, usare i Get-PsBreakpoint
cmdlet e Remove-PsBreakpoint
.
PS C:\ps-test> Get-PSBreakpoint| Remove-PSBreakpoint
Creare un nuovo punto di interruzione del comando nella psversion
funzione.
PS C:\ps-test> Set-PSBreakpoint -command psversion -script test.ps1
È possibile abbreviare questo comando per:
PS C:\ps-test> sbp -c psversion -s test.ps1
Eseguire ora lo script.
PS C:\ps-test> .\test.ps1
Hit Command breakpoint on 'C:\ps-test\test.ps1:psversion'
test.ps1:12 psversion
DBG>
Lo script raggiunge il punto di interruzione alla chiamata di funzione. A questo punto, la funzione non è ancora stata chiamata. In questo modo è possibile usare il parametro Action di Set-PSBreakpoint
per impostare le condizioni per l'esecuzione del punto di interruzione o per eseguire attività preliminari o diagnostiche, ad esempio l'avvio di un log o la chiamata di uno script di diagnostica o di sicurezza.
Per impostare un'azione, usare un comando Continue (c) per uscire dallo script e un Remove-PsBreakpoint
comando per eliminare il punto di interruzione corrente. I punti di interruzione sono di sola lettura, quindi non è possibile aggiungere un'azione al punto di interruzione corrente.
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>
A questo punto, creare un nuovo punto di interruzione del comando con un'azione. Il comando seguente imposta un punto di interruzione del comando con un'azione che registra il valore della $scriptName
variabile quando viene chiamata la funzione. Poiché la break
parola chiave non viene usata nell'azione, l'esecuzione non si arresta. Il backtick (`
) è il carattere di continuazione della riga.
PS C:\ps-test> Set-PSBreakpoint -command psversion -script test.ps1 `
-action { add-content "The value of `$scriptName is $scriptName." `
-path action.log}
È anche possibile aggiungere azioni che impostano condizioni per il punto di interruzione. Nel comando seguente il punto di interruzione del comando viene eseguito solo se i criteri di esecuzione sono impostati su RemoteSigned, i criteri più restrittivi che consentono comunque di eseguire gli script.
PS C:\ps-test> Set-PSBreakpoint -script test.ps1 -command psversion `
-action { if ((Get-ExecutionPolicy) -eq "RemoteSigned") { break }}
La break
parola chiave nell'azione indica al debugger di eseguire il punto di interruzione. È anche possibile usare la continue
parola chiave per indirizzare l'esecuzione del debugger senza interruzioni. Poiché la parola chiave predefinita è continue
, è necessario specificare per arrestare break
l'esecuzione.
Eseguire ora lo script.
PS C:\ps-test> .\test.ps1
Hit Command breakpoint on 'C:\ps-test\test.ps1:psversion'
test.ps1:12 psversion
Poiché i criteri di esecuzione sono impostati su RemoteSigned, l'esecuzione si arresta alla chiamata di funzione.
A questo punto, è possibile controllare lo stack di chiamate. Usare il Get-PsCallStack
cmdlet o il Get-PsCallStack
comando debugger (k
). Il comando seguente ottiene lo stack di chiamate corrente.
DBG> k
2: prompt
1: .\test.ps1: $args=[]
0: prompt: $args=[]
Questo esempio illustra solo alcuni dei molti modi per usare il debugger di PowerShell.
Altre funzionalità di debug in PowerShell
Oltre al debugger di PowerShell, PowerShell include diverse altre funzionalità che è possibile usare per eseguire il debug di script e funzioni.
Il
Set-PSDebug
cmdlet offre funzionalità di debug di script molto di base, tra cui istruzioni e traccia.Usare il
Set-StrictMode
cmdlet per rilevare i riferimenti alle variabili non inizializzate, ai riferimenti a proprietà inesistenti di un oggetto e alla sintassi della funzione non valida.Aggiungere istruzioni di diagnostica a uno script, ad esempio istruzioni che visualizzano il valore di variabili, istruzioni che leggono l'input dalla riga di comando o istruzioni che segnalano l'istruzione corrente. Usare i cmdlet che contengono il verbo Write per questa attività, ad esempio
Write-Host
,Write-Debug
Write-Warning
, eWrite-Verbose
.