Skript-Debugging für die PowerShell (2)

Lesezeit
3 Minuten
Bis jetzt gelesen

Skript-Debugging für die PowerShell (2)

09.02.2026 - 07:00
Veröffentlicht in:

In PowerShell-Skripte für die Automatisierung der IT-Aufgaben schleichen sich unweigerlich Fehler ein. Das macht den IT-Verantwortlichen nicht gleich zu einem schlechten Skripter, er muss jedoch Bugs identifizieren und ausmerzen, bevor sie in der Produktionsumgebung für Chaos sorgen. Im zweiten Teil der Workshopserie schauen wir uns an, wie Sie falsch eingesetzte Variablen vermeiden und warum Sie bei der Skriptentwicklung immer die vorhandene Infrastruktur berücksichtigen müssen.

Auch Namen und Scopes von Variablen sind eine verbreitete Fehlerursache. Die PowerShell verlangt von Ihnen nicht, dass Sie Variablen vor der Verwendung initialisieren. Entdeckt die PowerShell beim Abarbeiten des Skripts einen neuen Variablennamen, weist diese dieser Variable $null zu und arbeitet damit, bis die Variable einen neuen Wert bekommt. Ungewollt entsteht diese Situation, wenn Sie sich bei einem Variablennamen verschreiben – die Syntaxprüfung der PowerShell-Editoren hilft hier nicht weiter, denn es ist ja ein aus Sicht der Sprache legitimer Vorgang. Die PowerShell-Erweiterung von VSCode überwacht immerhin den umgekehrten Fall, wenn Sie eine Variable mit einem Wert bestücken, aber niemals einsetzen. Gegen einen Tippfehler im Variablennamen hilft dies nur dann, wenn die Zeile mit dem Tippfehler die einzige Verwendung dieser Variablen darstellt.

Variablen falsch eingesetzt

Ein weiterer Fehlerfall, der noch schwieriger aufzuspüren ist, entsteht dann, wenn Variablen in unterschiedlichen Scopes, zum Beispiel innerhalb und außerhalb von Funktionen, erstellt oder verwendet werden. Nutzen Sie eine Variable innerhalb einer Funktion, ohne dass sie explizit initialisiert oder als Parameter der Funktion deklariert ist, schaut die PowerShell nach, ob es die Variable nicht bereits im globalen Scope gibt. Änderungen, die die Funktion am Wert der Variablen vornimmt, werden zwar nicht an den globalen Scope zurückgegeben, der Ausgangswert innerhalb der Funktion wird jedoch aus dem globalen Scope übernommen. Oft entstehen solche Fehler bei Zähler- oder Indexvariablen, die einfach "$i" oder "$n" heißen und in verschiedenen Scopes gleichnamig vorhanden sein können.

Ein Sonderfall dieses Phänomens ist das Entwickeln von Skripten in einer grafischen Umgebung (PowerShell ISE oder Visual Studio Code mit der PowerShell-Erweiterung) und deren anschließende Ausführung in einer reinen Shell oder innerhalb einer Anwendung. Die Werte aller Variablen bleiben nach der Ausführung in der Sitzung des grafischen Codeeditors erhalten und mehrere Skripte, die gleichzeitig zum Bearbeiten geöffnet sind, haben Zugriff auf diese Werte. Auf diese Weise kann es passieren, dass ein Skript eine Variable initialisiert und ein anderes Skript in derselben Sitzung diesen Wert verwendet, ohne dass es selbst dafür gesorgt hat, dass der Wert zugewiesen wird.

PowerShell ISE mit mehreren Registerkarten, die unterschiedliche Ausführungsumgebungen für Skripte anzeigen.
Bild 2: Die unterschiedlich gezeichneten Tabs in PowerShell ISE entscheiden, in welcher Umgebung das Skript läuft.
 

Um diesem Verhalten vorzubeugen, sollten Sie sich angewöhnen, Skripte in unterschiedlichen Instanzen der Entwicklungsumgebung zu öffnen. In der PowerShell ISE erreichen Sie dies innerhalb eines Fensters indem Sie mit "Strg + T" eine neue "PowerShell-Registerkarte" öffnen. Diese Registerkarten laufen zwar innerhalb desselben Windows-Prozesses, die PowerShell-Umgebungen sind jedoch voneinander isoliert. Innerhalb einer Registerkarte können Sie mehrere Skripte öffnen, die sich die PowerShell-Umgebung teilen. In Visual Studio Code hingegen hilft nur das Starten einer neuen VSCode-Instanz.

Infrastruktur nicht berücksichtigt

Welche Entwicklungsumgebung Sie auch immer verwenden, Sie sollten sich angewöhnen, jedes Skript vor der Freigabe in Produktion in einer frisch gestarteten Umgebung laufen zu lassen, um Querwirkungen aus anderen Skripten oder aus dem bisherigen Entwicklungsprozess zuverlässig auszuschließen. Annahmen über die Umgebung zu treffen ist ein sehr häufiges Phänomen und diese rangieren vom Typ des Betriebssystems (32 oder 64 Bit, Server oder Client) über die verwendete PowerShell-Version bis hin zum Vorhandensein gewisser Funktionen. Letzteres zeigt sich beispielsweise oft in Skripten, die zur Exchange-Verwaltung dienen und stillschweigend davon ausgehen, dass sowohl die Exchange Management Shell als auch die RSAT-Cmdlets für das Active Directory installiert sind. Auch Mutmaßungen zu den Berechtigungen (lokale Adminrechte, Domain Admin) oder die Konnektivität (Erreichbarkeit bestimmter interner Services oder sogar Internetdienste) fallen in dieses Problemfeld.

Je nachdem, ob das Skript in einer interaktiven Sitzung oder unbeaufsichtigt ausgeführt werden soll, können Sie bei fehlenden Voraussetzungen entweder eine Warnung ausgeben oder das Skript stillschweigend beenden. Die Direktive "#requires" am Anfang des Skripts ermöglicht, zumindest einen Teil der Voraussetzungsprüfungen (administrative Sitzung mit erhöhten Rechten, PowerShell-Version und -Edition, vorhandene Module) in harte Ausführungsbedingungen zu verwandeln.

Einige der schwer lokalisierbaren Fehler wie das Verwenden nicht initialisierter Variablen oder Indexfehler bei Arrays machen Sie sichtbar, indem Sie Ihr Skript im "Strict Mode" ausführen. Dies erreichen Sie mit dem Set-StrictMode-Cmdlet. Ab Version 3.0 sind Sie damit gegen die meisten Tippfehler und gegen Array-Indexfehler insofern geschützt, als dass sie nicht stillschweigend zu Nullwerten, sondern zu Fehlermeldungen führen.

Im dritten Teil vergleichen wir konkret das Debuggen in der Shell und das Debuggen im Editor. Im ersten Teil ging es um die Besonderheiten des PowerShell-Debugging und verbreitete Fehlerquellen.

Über den Autor: Evgenij Smirnov ist Senior Solutions Architect bei Semperis und Microsoft-MVP für Cloud & Datacenter Management sowie VMware Certified Implementation Expert für Datacenter-Virtualisierung.