THEMA about_Debuggers KURZBESCHREIBUNG Beschreibt den Windows PowerShell-Debugger. DETAILBESCHREIBUNG Als Debuggen wird die Untersuchung eines Skripts während dessen Ausführung bezeichnet, bei der Fehler in den Skriptanweisungen erkannt und korrigiert werden. Der Windows PowerShell-Debugger wurde entworfen, um Ihnen das Untersuchen und Erkennen von Fehlern und Ineffizienzen in den Skripts zu erleichtern. Hinweis: Der Windows PowerShell-Debugger wird nicht remote ausgeführt. Zum Debuggen eines Skripts auf einem Remotecomputer kopieren Sie das Skript auf den lokalen Computer. Mit den Features des Windows PowerShell-Debuggers können Sie Windows PowerShell-Skripts, Funktionen, Befehle oder Ausdrücke während der Ausführung untersuchen. Der Windows PowerShell-Debugger umfasst einen Satz von Cmdlets, mit denen Sie Haltepunkte festlegen und verwalten sowie die Aufrufliste anzeigen können. Windows PowerShell bietet mehrere Methoden, mit denen Sie Skripts, Funktionen und Befehle debuggen können. Methode 1: Das Cmdlet "Set-PsDebug" bietet einfache Debugfeatures für Skripts, z. B. Durchlaufen und Ablaufverfolgung. Weitere Informationen erhalten Sie mit folgendem Befehl: "get-help set-psdebug". Methode 2: Verwenden Sie das Cmdlet "Set-StrictMode", um Verweise auf nicht initialisierte Variablen, Verweise auf nicht vorhandene Eigenschaften eines Objekts sowie Verweise auf ungültige Funktionssyntax zu erkennen. Methode 3: Fügen Sie einem Skript Diagnoseanweisungen hinzu, z. B. Anweisungen zum Anzeigen von Variablenwerten, Anweisungen zum Lesen der Eingabe in der Befehlszeile oder Anweisungen zum Melden der aktuellen Anweisung. Verwenden Sie die Cmdlets, die das Verb "Write" für diese Aufgabe enthalten, z. B. Write-Host, Write-Debug, Write-Warning und Write-Verbose. Methode 4: Debuggen Sie ein Skript mit dem Windows PowerShell-Debugger. Sie können den Debugger auch zum Debuggen einer Funktion oder eines Skriptblocks verwenden, den Sie an der Eingabeaufforder ung eingegeben haben. Sie können Haltepunkte festlegen, das Skript durchlaufen, die Werte von Variablen untersuchen, Diagnosen und Protokollierungsbefehle ausführen sowie die Aufrufliste anzeigen. Debugger-Cmdlets Der Windows PowerShell-Debugger umfasst den folgenden Satz von Cmdlets: Set-PsBreakpoint: Legt Haltepunkte für Zeilen, Variablen und Befehle fest. Get-PsBreakpoint: Ruft Haltepunkte in der aktuellen Sitzung ab. Disable-PsBreakpoint: Deaktiviert Haltepunkte in der aktuellen Sitzung. Enable-PsBreakpoint: Aktiviert Haltepunkte in der aktuellen Sitzung erneut. Remove-PsBreakpoint: Löscht Haltepunkte in der aktuellen Sitzung. Get-PsCallStack: Zeigt die aktuelle Aufrufliste an. Starten und Beenden des Debuggers Zum Starten des Debuggers legen Sie einen oder mehrere Haltepunkte fest. Führen Sie dann das Skript, den Befehl oder die Funktion für den Debugvorgang aus. Wenn Sie einen Haltepunkt erreichen, wird die Ausführung beendet, und die Steuerung wird an den Debugger übergeben. Zum Beenden des Debuggers führen Sie das Skript, den Befehl oder die Funktion vollständig aus. Sie können auch "stop" oder "t" eingeben. Debuggerbefehle Wenn Sie den Debugger an der Windows PowerShell-Konsole verwenden, steuern Sie die Ausführung mit den folgenden Befehlen. Hinweis: Informationen zum Verwenden des Debuggers in anderen Hostanwendungen finden Sie in der Dokumentation der Hostanwendung. s, Step-into Führt die nächste Anweisung aus und wird dann beendet. V, Step-over Führt die nächste Anweisung aus, überspringt jedoch Funktionen und Aufrufe. Die übersprungenen Anweisungen werden ausgeführt, jedoch nicht durchlaufen. o, Step-out Verlässt die aktuelle Funktion, setzt den Vorgang bei Schachtelung eine Ebene höher fort. Wird im Haupttext bis zum Ende oder zum nächsten Haltepunkt fortgesetzt. Die übersprungenen Anweisungen werden ausgeführt, jedoch nicht durchlaufen. c, Continue Setzt die Ausführung fort, bis das Skript abgeschlossen ist oder der nächste Haltepunkt erreicht wurde. Die übersprungenen Anweisungen werden ausgeführt, jedoch nicht durchlaufen. l, List Zeigt den Teil des Skripts an, der derzeit ausgeführt wird. Standardmäßig werden die aktuelle Zeile, fünf vorangehende Zeilen und 10 nachfolgende Zeilen angezeigt. Drücken Sie EINGABETASTE, um die Ausführung des Skripts fortzusetzen. l <m>, List Zeigt 16 Zeilen des Skripts an, beginnend mit der durch <m> angegebenen Zeilennummer. l <m> <n>, List Zeigt <n> Zeilen des Skripts an, beginnend mit der durch <m> angegebenen Zeilennummer. q, Stop Beendet die Skriptausführung und den Debugger. k, Get-PsCallStack Zeigt die aktuelle Aufrufliste an. <Eingabetaste> Wiederholt den letzten Befehl, wenn es sich dabei um "Step (s)", "Step-over (v)" oder "List (l)" handelte. Stellt andernfalls eine Sendeaktion dar. ?, h Zeigt den Hilfebefehl des Debuggers an. Zum Beenden des Debuggers verwenden Sie "Stop (q)". Im Debugger können Sie auch Befehle eingeben, den Wert von Variablen anzeigen, Cmdlets verwenden und Skripts ausführen. Mit diesen Debuggerbefehlen können Sie ein Skript ausführen, an einem wichtigen Punkt anhalten, die Werte von Variablen und den Status des Systems untersuchen sowie die Ausführung des Skripts fortsetzen, bis Sie ein Problem erkannt haben. Die Debuggerumgebung Wenn Sie einen Haltepunkt erreichen, greifen Sie auf die Debuggerumgebung zu. Die Eingabeaufforderung wird so geändert, dass sie mit "[DBG]:" beginnt. Sie können die Eingabeaufforderung anpassen. In einigen Hostanwendungen, z. B. der Windows PowerShell-Konsole (nicht jedoch in der Windows PowerShell Integrated Scripting Environment [ISE]) wird zudem eine geschachtelte Eingabeaufforderung zum Debuggen geöffnet. Die geschachtelte Eingabeaufforderung erkennen Sie an den sich wiederholenden Größer-als-Zeichen (ASCII 62), die an der Eingabeaufforderung angezeigt werden. Beispielsweise ist Folgendes die Standardeingabeaufforderung für das Debuggen in der Windows PowerShell-Konsole: [DBG]: PS (get-location)>>> Die Schachtelungsebene finden Sie mit der automatischen Variable "$NestedPromptLevel". Darüber hinaus wird die automatische Variable "$PSDebugContext" im lokalen Bereich definiert. Anhand des Vorhandenseins der Variablen "$PsDebugContext" können Sie ermitteln, ob Sie sich im Debugger befinden. Beispiel: if ($psdebugcontext) {"Debugging"} else {"Not Debugging"} Sie können den Wert der Variablen "$PSDebugContext" beim Debuggen verwenden. [DBG]: PS>>> $psdebugcontext.invocationinfo Name CommandLineParameters UnboundArguments Location ---- --------------------- ---------------- -------- = {} {} C:\ps-test\vote.ps1 (1) Debuggen und Bereich Der Bereich, in dem Sie arbeiten, wird durch Unterbrechen des Debuggers nicht geändert, wenn Sie jedoch einen Haltepunkt in einem Skript erreichen, bewegen Sie sich in den Skriptbereich. Der Skriptbereich bildet ein untergeordnetes Element des Bereichs, in dem Sie den Debugger ausgeführt haben. Zum Suchen der im Skriptbereich definierten Variablen und Aliase verwenden Sie den Scope-Parameter des Cmdlets "Get-Alias" oder "Get-Variable". Mit dem folgenden Befehl werden beispielsweise die Variablen im lokalen Bereich (Skriptbereich) abgerufen: get-variable -scope 0 Sie können den Befehl wie folgt abkürzen: gv -s 0 Dies ist eine nützliche Möglichkeit, nur die Variablen zu sehen, die Sie im Skript definiert haben und die Sie beim Debuggen definiert haben. Debuggen in der Befehlszeile Wenn Sie einen Variablenhaltepunkt oder einen Befehlshaltepunkt festgelegt haben, können Sie den Haltepunkt nur in einer Skriptdatei festlegen. Der Haltepunkt wird jedoch standardmäßig auf ein beliebiges Element festgelegt, das in der aktuellen Sitzung ausgeführt wird. Wenn Sie z. B. einen Haltepunkt für die Variable "$name" festlegen, wird der Debugger bei jeder Variablen "$name" in allen derzeit ausgeführten Skripts, Befehlen, Funktionen, Skript-Cmdlets und Ausdrücken unterbrochen, bis Sie den Haltepunkt deaktivieren oder entfernen. Dadurch können Sie die Skripts in einem realistischeren Kontext debuggen, in dem sich Funktionen, Variablen und andere Skripts in der Sitzung und im Benutzerprofil auswirken können. Zeilenhaltepunkte gelten nur für Skriptdateien, daher werden diese nur in Skriptdateien festgelegt. Debuggen von Funktionen Wenn Sie einen Haltepunkt für eine Funktion festlegen, die die Abschnitte "Begin", "Process" und "End" umfasst, wird der Debugger an der ersten Zeile jedes Abschnitts unterbrochen. Beispiel: 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 Starten von Debugmodus. Zum Aufrufen von Hilfe "h'" oder "?" verwenden. Erreichen von Befehlshaltepunkt in 'prompt:test-Cmdlet' test-cmdlet [DBG]: C:\PS> c Process Starten von Debugmodus. Zum Aufrufen von Hilfe "h'" oder "?" verwenden. Erreichen von Befehlshaltepunkt in 'prompt:test-Cmdlet' test-cmdlet [DBG]: C:\PS> c End Starten von Debugmodus. Zum Aufrufen von Hilfe "h'" oder "?" verwenden. Erreichen von Befehlshaltepunkt in 'prompt:test-Cmdlet' test-cmdlet [DBG]: C:\PS> Debuggen von Remoteskripts Sie können den Windows PowerShell-Debugger nicht in einer Remotesitzung ausführen. Zum Debuggen eines Skripts auf einem Remotecomputer kopieren Sie das Skript auf den lokalen Computer. Mit dem folgenden Befehl wird das Skript "Test.ps1" vom Remotecomputer "Server01" auf den lokalen Computer kopiert: invoke-command -computername Server01 ` {get-content c:\ps-test\test.ps1} | set-location c:\ps-test\test.ps1 Beispiele Dieses Testskript erkennt die Version des Betriebssystems und zeigt eine dem System entsprechende Meldung an. Es umfasst eine Funktion, einen Funktionsaufruf und eine Variable. Mit dem folgenden Befehl wird der Inhalt der Testskriptdatei angezeigt: c:>\PS-test> get-content test.ps1 function psversion { "Windows Powershell " + $psversiontable.psversion if ($psversiontable.psversion.major -lt 2) { "Update zu Windows PowerShell 2.0!" } else { "Haben Sie heute schon einen Hintergrundauftrag ausgeführt (start-job)?" } } $scriptname = $MyInvocation.MyCommand.Path psversion "Done $scriptname." Legen Sie zunächst einen Haltepunkt an einem wichtigen Punkt des Skripts fest, z. B. einer Zeile, einem Befehl, einer Variable oder einer Funktion. Beginnen Sie, indem Sie einen Zeilenhaltepunkt auf der ersten Zeile des Skripts "Test.ps1" im aktuellen Verzeichnis erstellen. PS C:\ps-test> set-psbreakpoint -line 1 -script test.ps1 Sie können diesen Befehl wie folgt abkürzen: PS C:\ps-test> spb 1 -s test.ps1 Der Befehl gibt ein Zeilenhaltepunktobjekt (System.Management. Automation.LineBreakpoint) zurück. Column : 0 Line : 1 Action : Enabled : True HitCount : 0 Id : 0 Script : C:\ps-test\test.ps1 ScriptName : C:\ps-test\test.ps1 Starten Sie jetzt das Skript. PS C:\ps-test> .\test.ps1 Wenn das Skript den ersten Haltepunkt erreicht, gibt die Haltepunktmeldung an, dass der Debugger aktiv ist. Es beschreibt den Haltepunkt und zeigt die erste Zeile des Skripts, eine Funktionsdeklaration, als Vorschau an. Die Eingabeaufforderung wird auch geändert, um anzugeben, dass die Steuerung beim Debugger liegt. Die Vorschauzeile umfasst den Skriptnamen und die Zeilennummer des in der Vorschau angezeigten Befehls. Starten von Debugmodus. Zum Aufrufen von Hilfe "h'" oder "?" verwenden. Zeilenhaltepunkt für 'C:\ps-test\test.ps1: 1' erreicht test.ps1:1 function psversion { DBG> Verwenden Sie den Befehl "Step" (s), um die erste Anweisung im Skript auszuführen und die nächste Anweisung als Vorschau anzuzeigen. In der nächsten Anweisung wird die automatische Variable "$MyInvocation" verwendet, um den Wert der Variablen "$ScriptName" auf den Pfad und Dateinamen der Skriptdatei festzulegen. DBG> s test.ps1:11 $scriptname = $MyInvocation.MyCommand.Path Zu diesem Zeitpunkt wird die Variable "$ScriptName" nicht aufgefüllt, doch können Sie den Wert der Variablen überprüfen, indem Sie deren Wert anzeigen. In diesem Fall ist der Wert $null. DBG> $scriptname DBG> Verwenden Sie einen anderen Befehl "Step" (s), um die aktuelle Anweisung auszuführen und die nächste Anweisung im Skript als Vorschau anzuzeigen. Mit der nächsten Anweisung wird die Funktion " PsVersion" aufgerufen. DBG> s test.ps1:12 psversion Zu diesem Zeitpunkt wird die Variable "$ScriptName" aufgefüllt, doch überprüfen Sie den Wert der Variablen, indem Sie deren Wert anzeigen. In diesem Fall wird der Wert auf den Skriptpfad festgelegt. DBG> $scriptname C:\ps-test\test.ps1 Verwenden Sie einen anderen Befehl "Step", um den Funktionsaufruf auszuführen. Drücken Sie EINGABETASTE, oder geben Sie "s" für Step ein. DBG> s test.ps1:2 "Windows PowerShell " + $psversiontable.psversion Die Debugmeldung enthält eine Vorschau der Anweisung in der Funktion. Zum Ausführen dieser Anweisung und Anzeigen der nächsten Anweisung in der Funktion als Vorschau können Sie den Befehl "Step" verwenden. Verwenden Sie in diesem Fall jedoch den Befehl "Step-Out" (o). Dieser schließt die Ausführung der Funktion ab (sofern kein Haltepunkt erreicht wird) und springt zur nächsten Anweisung im Skript. DBG> o Windows Powershell 2.0 Haben Sie heute schon einen Hintergrundauftrag ausgeführt (start-job)? test.ps1:13 "Done $scriptname" Da Sie sich bei der letzten Anweisung im Skript befinden, haben die Befehle "Step", "Step-Out" und "Continue" die gleiche Auswirkung. Verwenden Sie in diesem Fall Step-Out (o). Done C:\ps-test\test.ps1 PS C:\ps-test> Mit dem Befehl "Step-Out" wird der letzte Befehl ausgeführt. Die Standardeingabeaufforderung gibt an, dass der Debugger beendet wurde und die Steuerung an den Befehlsprozessor zurückgegeben hat. Führen Sie den Debugger jetzt erneut aus. Verwenden Sie zuerst, um den aktuellen Haltepunkt zu löschen, die Cmdlets "Get-PsBreakpoint" und "Remove-PsBreakpoint". (Wenn Sie den Haltepunkt möglicherweise wiederverwenden möchten, verwenden Sie statt Remove-PsBreakpoint das Cmdlet "Disable-PsBreakpoint".) PS C:\ps-test> Get-PsBreakpoint | Remove-PSBreakpoint Sie können diesen Befehl wie folgt abkürzen: PS C:\ps-test> gbp | rbp Sie können den Befehl durch Schreiben einer Funktion ausführen, beispielsweise der folgenden: function delbr { gbp | rbp } Erstellen Sie nun einen Haltepunkt für die Variable "$scriptname". PS C:\ps-test> set-psbreakpoint -variable Skriptname -script test.ps1 Sie können den Befehl wie folgt abkürzen: PS C:\ps-test> sbp -v Skriptname -s test.ps1 Starten Sie jetzt das Skript. Das Skript erreicht den Variablenhaltepunkt. Der Standardmodus ist "Write", daher wird die Ausführung genau vor der Anweisung beendet, von der der Wert der Variablen geändert wird. PS C:\ps-test> .\test.ps1 Erreichen von Variablenhaltepunkt bei 'C:\ps-test\test.ps1:$scriptname' (Schreibzugriff) test.ps1:11 $scriptname = $MyInvocation.mycommand.path DBG> Zeigen Sie den aktuellen Wert der Variablen "$scriptname", $null, an. DBG> $scriptname DBG> Verwenden Sie den Befehl "Step" (s), um die Anweisung auszuführen, mit der die Variable aufgefüllt wird. Zeigen Sie dann den neuen Wert der Variablen "$scriptname" an. DBG> $scriptname C:\ps-test\test.ps1 Verwenden Sie den Befehl "Step" (s), um die nächste Anweisung im Skript als Vorschau anzuzeigen. DBG> s test.ps1:12 psversion Die nächste Anweisung besteht in einem Aufruf der Funktion "PsVersion". Wenn die Funktion übersprungen, aber dennoch ausgeführt werden soll, verwenden Sie den Befehl "Step-Over" (v). Wenn Sie sich bei Verwendung von Step-Over bereits in der Funktion befinden, hat der Befehl keine Auswirkungen. Der Funktionsaufruf wird angezeigt, jedoch nicht ausgeführt. DBG> v Windows Powershell 2.0 Haben Sie heute schon einen Hintergrundauftrag ausgeführt (start-job)? test.ps1:13 "Done $scriptname" Mit dem Befehl "Step-Over" wird die Funktion ausgeführt und die nächste Anweisung im Skript, mit dem die letzte Zeile gedruckt wird, als Vorschau angezeigt. Beenden Sie den Debugger mit dem Befehl "Stop" (t). Die Eingabeaufforderung wird auf die Standardanzeige zurückgesetzt. C:\ps-test> Zum Löschen der Haltepunkte verwenden Sie die Cmdlets "Get-PsBreakpoint" und "Remove-PsBreakpoint". PS C:\ps-test> Get-PsBreakpoint | Remove-PSBreakpoint Erstellen Sie für die Funktion "PsVersion" einen neuen Befehlshaltepunkt. PS C:\ps-test> Set-PsBreakpoint -command psversion -script test.ps1 Sie können diesen Befehl wie folgt abkürzen: PS C:\ps-test> sbp -c psversion -s test.ps1 Führen Sie jetzt das Skript aus. PS C:\ps-test> .\test.ps1 Erreichen von Befehlshaltepunkt bei 'C:\ps-test\test.ps1:psversion' test.ps1:12 psversion DBG> Das Skript erreicht den Haltepunkt beim Funktionsaufruf. Zu diesem Zeitpunkt wurde die Funktion noch nicht aufgerufen. Dies gibt Ihnen die Gelegenheit, mit dem Action-Parameter "Set-PsBreakpoint" Bedingungen für die Ausführung des Haltepunkts festzulegen oder vorbereitende oder Diagnoseaufgaben auszuführen, z. B. ein Protokoll zu starten oder eine Diagnose oder ein Sicherheitsskript aufzurufen. Zum Festlegen einer Aktion verwenden Sie den Befehl "Continue" (c), um das Skript zu beenden, und den Befehl "Remove-PsBreakpoint", um den aktuellen Haltepunkt zu löschen. (Haltepunkte sind schreibgeschützt, deshalb können Sie dem aktuellen Haltepunkt keine Aktion hinzufügen.) DBG> c Windows PowerShell 2.0 Haben Sie heute schon einen Hintergrundauftrag ausgeführt (start-job)? Done C:\ps-test\test.ps1 PS C:\ps-test> get-psbreakpoint | remove-psbreakpoint PS C:\ps-test> Erstellen Sie nun einen neuen Befehlshaltepunkt mit einer Aktion. Mit dem folgenden Befehl wird einen Befehlshaltepunkt mit einer Aktion festgelegt, die beim Aufruf der Funktion den Wert der Variablen "$scriptname" protokolliert. Da das Break-Schlüsselwort in der Aktion nicht verwendet wird, wird die Ausführung nicht beendet. (Das Graviszeichen [`] wird als Zeilenfortsetzungszeichen verwendet.) PS C:\ps-test> set-psbreakpoint -command psversion -script test.ps1 ` -action { add-content "Der Wert von `$scriptname ist $scriptname." ` -path action.log} Sie können auch Aktionen hinzufügen, mit denen Bedingungen für den Haltepunkt festgelegt werden. Im folgenden Befehl wird der Befehlshaltepunkt nur ausgeführt, wenn die Ausführungsrichtlinie auf RemoteSigned festgelegt ist, die restriktivste Richtlinie, unter der Sie Skripts ausführen können. (Das Graviszeichen [`] wird als Fortsetzungszeichen verwendet.) PS C:\ps-test> set-psbreakpoint -script test.ps1 -command psversion ` -action { if ((get-executionpolicy) -eq "RemoteSigned") { break }} Mit dem Break-Schlüsselwort in der Aktion wird der Debugger angewiesen, den Haltepunkt auszuführen. Mit dem Continue-Schlüssel- wort können Sie den Debugger auch anweisen, die Ausführung ohne Unterbrechung vorzunehmen. Da als Standardschlüsselwort "Continue" festgelegt ist, müssen Sie Break angeben, um die Ausführung zu beenden. Führen Sie jetzt das Skript aus. PS C:\ps-test> .\test.ps1 Erreichen von Befehlshaltepunkt bei 'C:\ps-test\test.ps1:psversion' test.ps1:12 psversion Da die Ausführungsrichtlinie auf RemoteSigned festgelegt ist, wird die Ausführung beim Funktionsaufruf beendet. Zu diesem Zeitpunkt möchten Sie die Aufrufliste möglicherweise überprüfen. Verwenden Sie das Cmdlet "Get-PsCallStack" oder den Debuggerbefehl "Get-PsCallStack" (k). Mit dem folgenden Befehl wird die aktuelle Aufrufliste abgerufen. DBG> k 2: prompt 1: .\test.ps1: $args=[] 0: prompt: $args=[] In diesem Beispiel werden nur einige der zahlreichen Verwendungsmöglichkeiten des Windows PowerShell-Debuggers veranschaulicht. Weitere Informationen zu den Debugger-Cmdlets erhalten Sie, wenn Sie den folgenden Befehl eingeben: help <Cmdlet-Name> -full Geben Sie beispielsweise Folgendes ein: help set-psbreakpoint -full SIEHE AUCH Disable-PsBreakpoint Get-PsBreakpoint Remove-PsBreakpoint Set-PsBreakpoint Set-PsDebug Set-Strictmode Write-Debug Write-Verbose Enable-PsBreakpoint Get-PsCallStack