bluebay2014 - stock.adobe.com

PowerShell-Debugging: Visual Studio Code vs. native Konsole

Sollte man ein PowerShell-Skript in Visual Studio Code oder in der Konsole debuggen? Befolgen Sie dieses Tutorial, um die Entscheidung ein wenig zu erleichtern.

In PowerShell kann es schwierig sein, zwischen dem Schreiben eines Skripts und dem Debugging zu unterscheiden. Das Schreiben von Code in einer interpretierten Sprache macht es Admins leicht, jeden Schritt so auszuführen, wie sie ihn schreiben – ein Prozess, der sich allerdings recht schnell in ein Debugging verwandelt.

Es gibt zwei gängige Optionen zum Debuggen eines PowerShell-Skripts: die interaktive PowerShell-Konsole oder einen der vielen PowerShell-Code-Editoren. Für kurze Skripts bietet die Konsole zahlreiche Debugging-Funktionen, aber zum Debuggen längerer Skripts oder sogar Module sollte man einen Editor wie Visual Studio Code verwenden.

In diesem Tutorial wird anhand von Beispielen erläutert, wann die Konsole im Vergleich zu Visual Studio Code für das PowerShell-Debugging verwendet werden sollte.

Wann man in der Konsole debuggen sollte

Nehmen wir an, wir schreiben einen Code-Snippet, um das aktuelle Verzeichnis nach JSON-Protokolldateien zu durchsuchen, die das Jahr 2020 im Namen haben, und kopieren diese Dateien dann in ein anderes Verzeichnis.

Bevor Sie ein Skript an der Konsole ausführen, geben Sie einige erforderliche Variablen interaktiv in der Eingabeaufforderung ein:

$sourceDir = 'C:\tmp\logs'

$targetDir = 'C:\logs'

Geben Sie dann diesen Einzeiler ein (Hinweis: Da wir diesen Befehl interaktiv ausführen, ist es akzeptabel, Aliase zu verwenden, bei denen es sich um Befehlskürzel oder alternative Namen handelt):

gci $sourceDir -filter *20*.json | %{copy $_.FullName -Destination $targetDir} 

Nachdem dieser Code ausgeführt wurde, stellen wir fest, dass er Dateien kopiert, die wir nicht erwartet hatten – insbesondere Dateien aus dem letzten Jahr, obwohl der Filter im Cmdlet Get-ChildItem angibt, dass nur nach Dateien mit der Jahreszahl 20 gesucht werden soll.

Um dies zu beheben, fügen Sie einen Wait-Debugger-Befehl hinzu, der in den Debugger abgelegt wird:

gci $sourceDir -filter *20*.json | %{Wait-Debugger; copy $_ - Destination $targetDir}

Das sollte zu einem ähnlichen Ergebnis wie unten führen:

Abbildung 1
Abbildung 1

Jetzt haben Sie vollständigen Zugriff auf den PowerShell-Debugger. Verwenden Sie $_, um das aktuelle Element im Schleifen-Cmdlet ForEach-Object zu untersuchen.

Wie unten gezeigt, wird noch eine Datei aus dem Jahr 2019 angezeigt, da diese 20 enthält:

Abbildung 2
Abbildung 2

Um dies zu überprüfen, verwenden Sie C, um mit dem nächsten Schritt fortzufahren:

Abbildung 3
Abbildung 3

Wenn wir das nächste Objekt überprüfen, stellen wir fest, dass es sich tatsächlich um eine weitere Datei aus dem Jahr 2019 handelt. Beenden Sie also den Debugger mit q und korrigieren Sie den Code, um sicherzustellen, dass das neue Verzeichnis nur Dateien aus dem Jahr 2020 enthält:

gci $sourceDir -filter *20*.json | %{Wait-Debugger; copy $_ -Destination $targetDir}

Es ist möglich, dieses Snippet etwas intelligenter zu machen – zum Beispiel den Inhalt der Datei zu überprüfen, um sicherzustellen, dass der Zeitstempel in der Protokolldatei auch in diesem Jahr vorhanden ist. PowerShell ermöglicht es Admins zwar, lange Einzeiler zu schreiben, aber diese können zum Debuggen leicht unhandlich werden.

Es ist auch möglich, ein mehrzeiliges Skript interaktiv in PowerShell zu schreiben. Geben Sie einen Befehl ein und drücken Sie dann die Umschalt- sowie Eingabetaste (Shift-Enter), um eine neue Zeile zu beginnen. Dies bietet jedoch nur grundlegende Textbearbeitungsfunktionen.

Für fortgeschrittenere Funktionen ist es am besten, zum PowerShell-Debuggen zu Visual Studio Code zu wechseln.

Wann sollte man in Visual Studio Code debuggen?

In unserem Beispiel enthalten die JSON-Protokolldateien ein Array, wobei das erste Element das Datum ist, an dem die Datei erzeugt wurde. Zum Beispiel:

[

    "2020-01-17 18:05:01.325248",

    {...

Erweitern Sie das Skript aus dem vorigen Abschnitt, um auch eine Prüfung für dieses Datum hinzuzufügen:

$sourceDir = 'C:\tmp\logs'

$targetDir = 'C:\logs'

$files = Get-ChildItem $sourceDir -filter 2020*.json

foreach ($file in $files) {

    $json = Get-Content $file.FullName | ConvertTo-Json

    if ($json[0] -like '2020*') {

        Copy-Item $file.FullName -Destination $targetDir

    }

}

In Zeile sechs sehen wir das erste Element im konvertierten JSON-Array. Leider erscheinen nach der Ausführung des Codes keine Dateien im Zielverzeichnis; es ist Zeit für weiteres PowerShell-Debugging.

Setzen Sie den Cursor auf Zeile sechs und drücken Sie F9 auf der Tastatur, um einen Haltepunkt hinzuzufügen. Wenn der Code auf diese Zeile trifft, wird er im Debugger im Terminal abgelegt. Beachten Sie den roten Punkt links neben der Zeile:

Abbildung 4
Abbildung 4

Nachdem der Haltepunkt gesetzt ist, drücken Sie F5, um den Code auszuführen. Schauen Sie auf der linken Seite, wenn Sie durch das Debugger-Fenster blättern, in dem die Werte aller Variablen im Skript angezeigt werden:

Abbildung 5
Abbildung 5

Sie können das aktuelle $file, die Anzahl der Objekte im $files-Array und sogar die Variable $json sehen. Wenn Sie sich die $json-Variable genauer ansehen möchten, verwenden Sie die gleichen PowerShell-Debugging-Funktionen von der Konsole im Terminal aus. Geben Sie folgendes ein:

$json[0]

Die unten gezeigten Ergebnisse entsprechen nicht den Erwartungen, da das erste Element in der $json-Variablen ein '[' anstelle des Datums ist:

Abbildung 6
Abbildung 6

Um zu sehen, um welche Art von Objekt es sich bei $json handelt, bewegen Sie den Mauszeiger über die Variable im Debugger-Fenster oder untersuchen Sie die Variable direkt. In beiden Fällen wird in den Ergebnissen ein String angezeigt:

Abbildung 7
Abbildung 7

Das Cmdlet ConvertFrom-Json sollte jedoch ein Objekt – wie in diesem Beispiel beabsichtigt – und kein String erzeugen. Dies liegt daran, dass wir – wenn wir auf das Skript vom Anfang dieses Abschnitts zurückblicken – versehentlich ConvertTo-Json anstelle von ConvertFrom-Json verwenden.

Der korrigierte Code sollte wie folgt aussehen:

$sourceDir = 'D:\UtoData'

$targetDir = 'C:\logs'

$files = Get-ChildItem $sourceDir -filter 2020*.json

foreach ($file in $files) {

    $json = Get-Content $file.FullName | ConvertFrom-Json

    if ($json[0] -like '2020*') {

        Copy-Item $file.FullName -Destination $targetDir

    }

}

Belassen Sie den Haltepunkt auf Zeile sechs und führen Sie den Code erneut mit F5 aus und werfen Sie einen weiteren Blick auf die Variable $json:

Abbildung 8
Abbildung 8

Die Ergebnisse sehen jetzt wie erwartet aus, da wir nun ein Objekt statt eines String haben. Dies bedeutet, dass ConvertFrom-Json funktioniert hat. Um den Haltepunkt zu entfernen, setzen Sie den Cursor wieder auf Zeile sechs und drücken Sie F9. Drücken Sie jetzt erneut F5, und der Code wird wie beabsichtigt ausgeführt.

Erfahren Sie mehr über Softwareentwicklung

ComputerWeekly.de

Close