ARGOMENTO about_Debuggers DESCRIZIONE BREVE Descrive il debugger di Windows PowerShell. DESCRIZIONE DETTAGLIATA Per debug si intende il processo attraverso il quale uno script viene esaminato durante la sua esecuzione allo scopo di identificare e correggere eventuali errori presenti nelle istruzioni. Il debugger di Windows PowerShell è stato progettato per consentire l'esame e l'identificazione degli errori e delle inefficienze eventualmente presenti negli script. Nota: il debugger di Windows PowerShell non può essere eseguito in modalità remota. Per eseguire il debug di uno script in un computer remoto, copiare lo script nel computer locale. È possibile utilizzare le funzionalità del debugger di Windows PowerShell per esaminare uno script, una funzione, un comando o un'espressione di Windows PowerShell durante la relativa esecuzione. Il debugger di Windows PowerShell include un insieme di cmdlet che consentono di impostare e gestire punti di interruzione e di visualizzare lo stack di chiamate. Windows PowerShell offre diversi metodi per il debug di script, funzioni e comandi. Metodo 1: il cmdlet Set-PsDebug offre funzionalità di debug di script di base, inclusi il debug passo passo e l'analisi. Per ulteriori informazioni, digitare: "get-help set-psdebug". Metodo 2: utilizzare il cmdlet Set-StrictMode per rilevare riferimenti a variabili non inizializzate, a riferimenti a proprietà inesistenti di un oggetto e a sintassi di funzioni non valida. Metodo 3: aggiungere istruzioni di diagnostica a uno script, ad esempio istruzioni per la visualizzazione del valore delle variabili, istruzioni per la lettura dell'input dalla riga di comando oppure istruzioni che segnalano l'istruzione corrente. Utilizzare i cmdlet che contengono il verbo Write per questa attività, ad esempio Write-Host, Write-Debug, Write-Warning e Write-Verbose. Metodo 4: utilizzare il debugger di Windows PowerShell per eseguire il debug di uno script. In alternativa, utilizzare il debugger per eseguire il debug di una funzione o di un blocco di script digitati al prompt dei comandi. È possibile impostare punti di interruzione, eseguire passo passo lo script, esaminare i valori delle variabili, eseguire i comandi di diagnostica e registrazione e visualizzare lo stack di chiamate. Cmdlet del debugger Il debugger di Windows PowerShell include l'insieme di cmdlet seguente: Set-PsBreakpoint: imposta punti di interruzione su righe, variabili e comandi. Get-PsBreakpoint: ottiene punti di interruzione nella sessione corrente. Disable-PsBreakpoint: disattiva i punti di interruzione nella sessione corrente. Enable-PsBreakpoint: riattiva 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. Eseguire lo script, il comando o la funzione di cui si desidera eseguire il debug. Quando si raggiunge un punto di interruzione, l'esecuzione viene arrestata e il controllo viene assunto dal debugger. Per arrestare il debugger, eseguire lo script, il comando o la funzione fino al relativo completamento. In alternativa, digitare "stop" o "t". Comandi del debugger Quando si utilizza il debugger nella console di Windows PowerShell, utilizzare i comandi seguenti per controllare l'esecuzione. Nota: per informazioni su come utilizzare il debugger in altre applicazioni host, vedere la documentazione dell'applicazione host. s, Step-into Esegue l'istruzione successiva, quindi si arresta. v, Step-over Esegue l'istruzione successiva, ma ignora funzioni e chiamate. Le istruzioni ignorate vengono eseguite, ma non passo passo. o, Step-out Interrompe l'esecuzione della funzione corrente; passa al livello successivo se nidificata. Se nel corpo principale, continua fino alla fine o al punto di interruzione successivo. Le istruzioni ignorate vengono eseguite, ma non passo passo. 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 passo passo. l, List Visualizza la parte dello script in esecuzione. Per impostazione predefinita, visualizza la riga corrente, le cinque righe precedenti e le 10 righe successive. Per continuare a elencare lo script, premere INVIO. l <m>, List Visualizza 16 righe dello script a partire dalla riga con il numero specificato da <m>. l <m> <n>, List Visualizza <n> righe dello script, a partire dalla riga con il numero specificato da <m>. q, Stop Arresta l'esecuzione dello script e chiude il debugger. k, Get-PsCallStack Visualizza lo stack di chiamate corrente. <Invio> Ripete l'ultimo comando se si trattava di Step (s), Step-over (v) o List (l). In caso contrario, rappresenta un'azione di invio. ?, h Visualizza la Guida dei comandi del debugger. Per chiudere il debugger, utilizzare Stop (q). Con il debugger aperto, è anche possibile immettere comandi, visualizzare il valore delle variabili, utilizzare cmdlet ed eseguire script. Mediante questi comandi del debugger, è possibile eseguire uno script, arrestarsi su un punto problematico, esaminare i valori delle variabili e lo stato del sistema e continuare l'esecuzione dello script finché non viene identificato un problema. Ambiente del debugger Quando si raggiunge un punto di interruzione, si accede all'ambiente del debugger. Il prompt dei comandi cambia per iniziare con "[DBG]:". È possibile personalizzare il prompt. Inoltre, in alcune applicazioni host, ad esempio la console di Windows PowerShell, (ma non Windows PowerShell Integrated Scripting Environment [ISE]), viene aperto un prompt nidificato per il debug. È possibile riconoscere il prompt nidificato grazie ai caratteri maggiore di ripetuti (ASCII 62) che vengono visualizzati al prompt dei comandi. Di seguito viene illustrato il prompt di debug predefinito nella console di Windows PowerShell: [DBG]: PS (get-location)>>> È possibile trovare il livello di nidificazione mediante la variabile automatica $NestedPromptLevel. Viene inoltre definita una variabile automatica, $PSDebugContext, nell'ambito locale. È possibile utilizzare la presenza della variabile $PsDebugContext per determinare se il debugger è attualmente aperto. Ad esempio: if ($psdebugcontext) {"Debugging"} else {"Not Debugging"} È possibile utilizzare il valore della variabile $PSDebugContext nel debug. [DBG]: PS>>> $psdebugcontext.invocationinfo Name CommandLineParameters UnboundArguments Location ---- --------------------- ---------------- -------- = {} {} C:\ps-test\vote.ps1 (1) Debug e ambito L'accesso al debugger non modifica l'ambito nel quale viene eseguito, tuttavia quando si raggiunge un punto di interruzione in uno script, ci si sposta nell'ambito dello script. L'ambito dello script è un elemento figlio dell'ambito nel quale è stato eseguito il debugger. Per trovare le variabili e gli alias definiti nell'ambito dello script, utilizzare il parametro Scope del cmdlet Get-Alias o Get-Variable. Ad esempio, il comando seguente ottiene le variabili nell'ambito locale (script): get-variable -scope 0 È possibile abbreviare il comando in: gv -s 0 Si tratta di un metodo utile per visualizzare unicamente le variabili definite nello script durante il debug. Esecuzione del debug alla riga di comando Quando si imposta un punto di interruzione variabile o un punto di interruzione 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 venga eseguito nella sessione corrente. Ad esempio, se si imposta un punto di interruzione sulla variabile $name, il debugger si arresta in corrispondenza di qualsiasi variabile $name in qualsiasi script, comando, funzione, cmdlet di script o espressione eseguita finché il punto di interruzione non viene disabilitato o rimosso. In questo modo, è possibile eseguire il debug degli script in un contesto più realistico in cui potrebbero essere interessati da funzioni, variabili e da altri script nella sessione e nel profilo utente. Poiché i punti di interruzione riga sono specifici dei file di script, vengono impostati solo nei file di script. Esecuzione del debug di funzioni Quando si imposta un punto di interruzione su una funzione con sezioni Begin, Process e End, il debugger si arresta 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> Esecuzione del debug di script remoti Non è possibile eseguire il debugger di Windows PowerShell in una sessione remota. Per eseguire il debug di uno script in un computer remoto, copiare lo script nel computer locale. Il comando seguente copia lo script Test.ps1 dal computer remoto Server01 al computer locale: invoke-command -computername Server01 ` {get-content c:\ps- test\test.ps1} | set-location c:\ps-test\test.ps1 Esempi Questo script di test rileva la versione del sistema operativo e visualizza un messaggio appropriato. Sono inclusi una funzione, una chiamata di funzione e una variabile. Il comando seguente visualizza il contenuto del file di script di test: c:>\PS-test> get-content test.ps1 function psversion { "Windows Powershell " + $psversiontable.psversion if ($psversiontable.psversion.major -lt 2) { "Upgrade to Windows PowerShell 2.0!" } else { "Have you run a background job today (start-job)?" } } $scriptname = $MyInvocation.MyCommand.Path psversion "Done $scriptname." Per iniziare, impostare un punto di interruzione su un punto dello script di particolare interesse, ad esempio una riga, un comando, una variabile o una funzione. Creare innanzitutto un punto di interruzione riga in corrispondenza della prima riga dello script Test.ps1 nella directory corrente. PS C:\ps-test> set-psbreakpoint -line 1 -script test.ps1 È possibile abbreviare il comando in: PS C:\ps-test> spb 1 -s test.ps1 Il comando restituisce un oggetto punto di interruzione riga (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 relativo indica che il debugger è attivo. Descrive il punto di interruzione e visualizza un'anteprima della prima riga dello script, che consiste in una dichiarazione di funzione. Il prompt dei comandi cambia per indicare che il debugger ha assunto il controllo. La riga di anteprima include il nome dello script e il numero di riga del comando 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> Utilizzare il comando Step (s) per eseguire la prima istruzione nello script e per visualizzare in anteprima l'istruzione successiva. L'istruzione successiva utilizza la variabile automatica $MyInvocation per impostare il valore della variabile $ScriptName sul percorso e sul nome del file di script. DBG> s test.ps1:11 $scriptname = $MyInvocation.MyCommand.Path A questo punto, la variabile $ScriptName non è compilata, tuttavia è possibile verificarne il valore visualizzandolo. In questo caso, il valore è $null. DBG> $scriptname DBG> Utilizzare un altro comando Step (s) per eseguire l'istruzione corrente e per visualizzare in anteprima l'istruzione successiva nello script. L'istruzione successiva chiama la funzione PsVersion. DBG> s test.ps1:12 psversion A questo punto, la variabile $ScriptName è compilata, ma è possibile verificarne il valore visualizzandolo. In questo caso, il valore viene impostato sul percorso dello script. DBG> $scriptname C:\ps-test\test.ps1 Utilizzare un altro comando Step per eseguire la chiamata di funzione. Premere INVIO oppure digitare "s" per Step. DBG> s test.ps1:2 "Windows 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 utilizzare un comando Step. Tuttavia, in questo caso, utilizzare un comando Step-Out (o). Questo comando completa l'esecuzione della funzione (a meno che non venga raggiunto un punto di interruzione) e passa 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 è giunti all'ultima istruzione nello script, i comandi Step, Step-Out e Continue producono lo stesso effetto. In questo caso, utilizzare Step-Out (o). Done C:\ps-test\test.ps1 PS C:\ps-test> Il comando Step-Out esegue l'ultimo comando. Il prompt dei comandi standard indica che il debugger è stato chiuso e che ha restituito il controllo al processore dei comandi. Eseguire nuovamente il debugger. Innanzitutto, per eliminare il punto di interruzione corrente, utilizzare i cmdlet Get-PsBreakpoint e Remove-PsBreakpoint. (Se si pensa di riutilizzare il punto di interruzione, utilizzare il cmdlet Disable-PsBreakpoint anziché Remove-PsBreakpoint.) 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 seguente: function delbr { gbp | rbp } Creare un punto di interruzione sulla variabile $scriptname. PS C:\ps-test> set-psbreakpoint -variable scriptname -script test.ps1 È possibile abbreviare il comando in: PS C:\ps-test> sbp -v scriptname -s test.ps1 A questo punto, avviare lo script. Lo script raggiunge il punto di interruzione variabile. La modalità predefinita è Write, pertanto l'esecuzione viene arrestata 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.mycommand.path DBG> Visualizzare il valore corrente della variabile $scriptname, ovvero $null. DBG> $scriptname DBG> Utilizzare un comando Step (s) per eseguire l'istruzione che compila la variabile. Visualizzare il nuovo valore della variabile $scriptname. DBG> $scriptname C:\ps-test\test.ps1 Utilizzare 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 funzione PsVersion. Per ignorare la funzione ma comunque eseguirla, utilizzare un comando Step-Over (v). Se ci si trova già nella funzione quando si utilizza Step-Over, non si ottiene alcun risultato. La chiamata di funzione viene visualizzata, ma non eseguita. DBG> v Windows Powershell 2.0 Have you run a background job today (start-job)? test.ps1:13 "Done $scriptname" Il comando Step-Over esegue la funzione, quindi visualizza in anteprima l'istruzione successiva nello script che stampa la riga finale. Utilizzare un comando Stop (t) per chiudere il debugger. Viene ripristinato il prompt dei comandi standard. C:\ps-test> Per eliminare i punti di interruzione, utilizzare i cmdlet Get- PsBreakpoint e Remove-PsBreakpoint. PS C:\ps-test> Get-PsBreakpoint | Remove-PSBreakpoint Creare un nuovo punto di interruzione comando sulla funzione PsVersion. PS C:\ps-test> Set-PsBreakpoint -command psversion -script test.ps1 È possibile abbreviare questo comando come: PS C:\ps-test> sbp -c psversion -s test.ps1 A questo punto, eseguire 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 si ha l'opportunità di utilizzare il parametro Action di Set-PsBreakpoint per impostare condizioni per l'esecuzione del punto di interruzione o per svolgere attività preparatorie o diagnostiche, ad esempio l'avvio di un registro o la chiamata a uno script di diagnostica o sicurezza. Per impostare un'azione, utilizzare un comando Continue (c) per uscire dallo script e un comando Remove-PsBreakpoint per eliminare il punto di interruzione corrente. (Poiché i punti di interruzione sono in sola lettura, 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> Creare un nuovo punto di interruzione comando con un'azione. Il comando seguente imposta un punto di interruzione comando con un'azione che registra il valore della variabile $scriptname quando viene chiamata la funzione. Poiché la parola chiave Break non viene utilizzata nell'azione, l'esecuzione non viene arrestata. Il simbolo di apice inverso (`) è 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} È inoltre possibile aggiungere azioni che impostano condizioni per il punto di interruzione. Nel comando seguente, il punto di interruzione comando viene eseguito solo se i criteri di esecuzione sono impostati su RemoteSigned, i criteri più restrittivi che consentono comunque l'esecuzione degli script. Il simbolo di apice inverso (`) è il carattere di continuazione. PS C:\ps-test> set-psbreakpoint -script test.ps1 -command psversion ` -action { if ((get-executionpolicy) -eq "RemoteSigned") { break }} La parola chiave Break nell'azione indica al debugger di eseguire il punto di interruzione. È inoltre possibile utilizzare la parola chiave Continue per indicare al debugger di procedere all'esecuzione senza interruzione. Poiché la parola chiave predefinita è Continue, è necessario specificare Break per arrestare l'esecuzione. A questo punto, eseguire 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 viene arrestata alla chiamata di funzione. A questo punto, è necessario controllare lo stack di chiamate. Utilizzare il cmdlet Get-PsCallStack o il comando del debugger Get- PsCallStack (k). Il comando seguente ottiene lo stack di chiamate corrente. DBG> k 2: prompt 1: .\test.ps1: $args=[] 0: prompt: $args=[] In questo esempio sono illustrati solo alcuni dei diversi metodi disponibili per l'utilizzo del debugger di Windows PowerShell. Per ulteriori informazioni sui cmdlet del debugger, digitare il comando seguente: help <cmdlet-name> -full Ad esempio, digitare: help set-psbreakpoint -full VEDERE ANCHE Disable-PsBreakpoint Get-PsBreakpoint Remove-PsBreakpoint Set-PsBreakpoint Set-PsDebug Set-Strictmode Write-Debug Write-Verbose Enable-PsBreakpoint Get-PsCallStack