Haben Sie jemals ein Skript oder einen PowerShell-Cmdlet ausgeführt und wurden mit einer Wand aus Text – in Rot – wie der unten gezeigten konfrontiert?

Fehler können überwältigend und verwirrend sein. Und vor allem sind Fehler oft schwer lesbar, was es nahezu unmöglich macht, festzustellen, was und wo das Skript schief gelaufen ist.
Zum Glück haben Sie in PowerShell einige Optionen, um dies durch Fehlerbehandlung zu verbessern. Mit Fehlerbehandlung können Fehler gefiltert und in einer Weise angezeigt werden, die es einfacher macht, sie zu verstehen. Und das Verständnis des Fehlers erleichtert das Hinzufügen von mehr Logik zur Fehlerbehandlung.
In diesem Artikel erfahren Sie mehr über Fehler in PowerShell und wie sie abgefangen werden können, um Fehlerbehandlung mit den PowerShell Try Catch
-Blöcken (und finally
-Blöcken) durchzuführen.
Verständnis, wie Fehler in PowerShell funktionieren
Bevor wir uns mit der Fehlerbehandlung beschäftigen, wollen wir zunächst einige Konzepte rund um Fehler in PowerShell erläutern. Das Verständnis von Fehlern kann zu besseren Fehlerbehandlungsstrategien führen.
Die Automatische Variable $Error
In PowerShell gibt es viele automatische Variablen, und eine davon ist die Automatische Variable $Error
. PowerShell verwendet die Variable $Error
, um alle Fehler zu speichern, die in der Sitzung auftreten. Die Variable $Error
ist ein Array von Fehlern, sortiert nach dem neuesten.
Wenn Sie eine PowerShell-Sitzung öffnen, ist die Variable $Error
zu Beginn leer. Sie können dies überprüfen, indem Sie die Variable $Error
aufrufen.

Wie Sie sehen können, ist die Variable $Error
zu Beginn leer. Sobald jedoch ein Fehler auftritt, wird der Fehler zur $Error
-Variable hinzugefügt und gespeichert.
Im folgenden Beispiel wird der Fehler absichtlich generiert, indem ein Dienstname angefordert wird, der nicht existiert.

Wie Sie aus der obigen Ausgabe sehen können, wurde der generierte Fehler zur $Error
-Variable hinzugefügt.
Die Variable $Error enthält eine Sammlung von Fehlern, die in der PowerShell-Sitzung generiert wurden. Jeder Fehler kann durch Aufrufen seiner Arrayposition abgerufen werden. Der neueste Fehler befindet sich immer an Index 0.
Zum Beispiel kann der neueste Fehler mit
$Error[0]
abgerufen werden.
Die Eigenschaften des Objekts $Error
Da in PowerShell alles ein Objekt ist, ist die Variable $Error
ein Objekt und Objekte haben Eigenschaften. Wenn Sie die Variable $Error
an den Befehl Get-Member
weiterleiten, sollten Sie die Liste der verfügbaren Eigenschaften sehen können.

Um den Grund für den Fehler zu ermitteln, können Sie den Inhalt der Eigenschaft InvocationInfo
mit dem folgenden Befehl anzeigen.

Nun können Sie dasselbe mit den anderen Eigenschaften tun und herausfinden, welche weiteren Informationen Sie finden können!
Beendigende Fehler
Beendigungsfehler unterbrechen den Ausführungsfluss, wenn sie von PowerShell im Gegensatz zu nicht beendigenden Fehlern festgestellt werden. Es gibt mehrere Möglichkeiten, wie ein Beendigungsfehler auftreten kann. Ein Beispiel ist, wenn Sie einen cmdlet mit einem nicht vorhandenen Parameter aufrufen.
Wie Sie unten auf dem Screenshot sehen können, wenn der Befehl Get-Process notepad
ausgeführt wird, ist der Befehl gültig und die Details des notepad-Prozesses werden angezeigt.

Aber wenn ein nicht vorhandener Parameter verwendet wird, wie z.B. Get-Process notepad -handle 251
, zeigt das cmdlet einen Fehler an, dass der handle
-Parameter ungültig ist. Dann beendet das cmdlet ohne Anzeige der Details des notepad
-Prozesses.

Nicht-beendigende Fehler
Nicht-beendigende Fehler sind Fehler, die die Ausführung des Skripts oder Befehls nicht stoppen. Schauen Sie sich zum Beispiel den folgenden Code an. Dieser Code ruft die Liste der Dateinamen aus der Datei fileslist.txt ab. Anschließend geht das Skript jeden Dateinamen durch, liest den Inhalt jeder Datei und gibt ihn auf dem Bildschirm aus.
Der Inhalt der Datei filelist.txt sind die Dateinamen in der untenstehenden Liste dargestellt.
Aber was ist, wenn File_6.log tatsächlich nicht existiert? Wenn Sie den Code ausführen, erwarten Sie einen Fehler, da das Skript die File_6.log-Datei nicht finden kann. Sie sehen eine ähnliche Ausgabe wie unten angezeigt.

Wie Sie am Screenshot des oben stehenden Ergebnisses sehen können, konnte das Skript die ersten fünf Dateien in der Liste lesen, aber als es versuchte, die Datei File_6.txt zu lesen, wurde ein Fehler zurückgegeben. Das Skript fuhr dann damit fort, den Rest der Dateien zu lesen, bevor es beendet wurde. Es wurde nicht beendet.
Die Variable $ErrorActionPreference
Bisher haben Sie gelernt, dass es terminierende und nicht-terminierende Fehler gibt und wie sie sich voneinander unterscheiden. Aber wussten Sie, dass ein nicht-terminierender Fehler dazu gezwungen werden kann, wie ein terminierender Fehler behandelt zu werden?
PowerShell hat ein Konzept namens Referenzvariablen. Diese Variablen werden verwendet, um das Verhalten von PowerShell auf viele verschiedene Arten zu ändern. Eine dieser Variablen heißt $ErrorActionPreference
.
Die Variable $ErrorActionPreference
wird verwendet, um die Art und Weise zu ändern, wie PowerShell nicht-terminierende Fehler behandelt. Standardmäßig ist der Wert von $ErrorActionPreference
auf Continue
festgelegt. Wenn Sie den Wert der Variable $ErrorActionPreference
auf STOP
ändern, zwingt PowerShell dazu, alle Fehler als terminierende Fehler zu behandeln.
Verwenden Sie den folgenden Code, um den Wert von $ErrorActionPreference
zu ändern.
Um mehr über andere gültige Werte der Variablen $ErrorActionPreference zu erfahren, besuchen Sie PowerShell ErrorActionPreference.
Verweisen Sie nun auf das Beispiel in Abschnitt Nicht-terminierende Fehler in diesem Artikel. Das Skript kann so geändert werden, dass die Änderung in $ErrorActionPreference
wie im folgenden Code angezeigt wird:
Wenn der oben modifizierte Code ausgeführt wird und der Wert von $ErrorActionPreference
auf den Standardwert Continue
gesetzt ist, verhält er sich anders als zuvor.

$ErrorActionPreference
variableWie im obigen Screenshot zu sehen ist, konnte das Skript die ersten fünf Dateien in der Liste lesen, aber als es versuchte, die Datei Datei_6.txt zu lesen, trat ein Fehler auf, da die Datei nicht gefunden wurde. Das Skript wurde dann beendet und der Rest der Dateien wurde nicht gelesen.
Der Wert von
$ErrorActionPreference
ist nur in der aktuellen PowerShell-Sitzung gültig. Er wird auf den Standardwert zurückgesetzt, sobald eine neue PowerShell-Sitzung gestartet wird.
Der gemeinsame Parameter ErrorAction
Wenn der Wert $ErrorActionPreference
auf die PowerShell-Sitzung angewendet wird, gilt der Parameter ErrorAction
für alle cmdlets, die allgemeine Parameter unterstützen. Der Parameter ErrorAction
akzeptiert dieselben Werte wie die Variable $ErrorActionPreference
.
Der Wert des Parameters ErrorAction
hat Vorrang vor dem Wert der Variable $ErrorActionPreference
.
Lassen Sie uns zum vorherigen Beispiel zurückkehren und denselben Code verwenden. Dieses Mal wird jedoch der Parameter ErrorAction
zur Zeile Get-Content
hinzugefügt.
Nach Ausführung des geänderten Codes sehen Sie, dass das Skript trotzdem beendet wird, obwohl $ErrorActionPreference
auf Continue
gesetzt ist. Das Skript wurde beendet, weil der Wert des PowerShell-ErrorAction
-Parameters in Get-Content
auf STOP
gesetzt ist.

ErrorAction
parameterVerwendung von PowerShell Try Catch-Blöcken
Bis jetzt haben Sie etwas über PowerShell-Fehler und die Funktionsweise der Variable $ErrorActionPreference
und des PowerShell-ErrorAction
-Parameters gelernt. Jetzt ist es an der Zeit, dass Sie das Gute kennenlernen – die PowerShell-Try Catch Finally
-Blöcke.
PowerShell try catch
Blöcke (und optionaler finally block
) dienen dazu, einen Bereich des Codes einzufassen und eventuelle Fehler abzufangen.
Der folgende Code zeigt die Syntax des Try
Statements.
Der Try
Block enthält den Code, den PowerShell „versuchen“ und auf Fehler überwachen soll. Wenn der Code im Try
Block einen Fehler erzeugt, wird der Fehler der $Error
Variable hinzugefügt und an den Catch
Block übergeben.
Der Catch
Block enthält die Aktionen, die ausgeführt werden sollen, wenn ein Fehler vom Try
Block empfangen wird. Es können mehrere Catch
Blöcke in einem Try
Statement vorhanden sein.
Der Finally
Block enthält den Code, der am Ende des Try
Statements ausgeführt wird. Dieser Block wird unabhängig davon ausgeführt, ob ein Fehler aufgetreten ist oder nicht.
Auffangen von nicht spezifischen Fehlern (Catch-All) mit PowerShell ErrorAction
A simple Try
statement contains a Try
and a Catch
block. The Finally
block is optional.
Zum Beispiel, um eine nicht spezifische Ausnahme abzufangen, sollte der Catch
Parameter leer sein. Der folgende Beispielcode verwendet das gleiche Skript wie im Abschnitt Die Variable $ErrorActionPreference, wurde jedoch so geändert, dass die Try Catch
Blöcke verwendet werden.
Wie Sie aus dem folgenden Code sehen können, ist dieses Mal die foreach
Anweisung im Try
Block eingeschlossen. Dann enthält ein Catch
Block den Code, um den Text „Ein Fehler ist aufgetreten“ anzuzeigen, falls ein Fehler auftritt. Der Code im Finally
Block löscht einfach die $Error
Variable.
Der obenstehende Code gibt nach dem Ausführen in PowerShell die folgende Ausgabe zurück.

Die obige Ausgabe zeigt, dass das Skript einen Fehler festgestellt hat, den Code im Catch
-Block ausgeführt und dann beendet hat.
Der Fehler wurde behandelt, was der Zweck der Fehlerbehandlung war. Allerdings war die angezeigte Fehlermeldung zu allgemein. Um einen detaillierteren Fehler anzuzeigen, könnten Sie auf die Exception
-Eigenschaft des Fehlers zugreifen, der vom Try
-Block übergeben wurde.
Der folgende Code wurde modifiziert, insbesondere der Code im Catch
-Block, um die Ausnahmemeldung des aktuellen Fehlers anzuzeigen, der an die Pipeline übergeben wurde – $PSItem.Exception.Message
Wenn der modifizierte Code oben ausgeführt wird, wird die angezeigte Meldung diesmal viel detaillierter sein.

Auffangen spezifischer Fehler
Es gibt Situationen, in denen eine allgemeine Fehlerbehandlung nicht der geeignetste Ansatz ist. Möglicherweise möchten Sie, dass Ihr Skript eine Aktion ausführt, die von der Art des aufgetretenen Fehlers abhängt.
Wie bestimmen Sie den Fehlertyp? Indem Sie den Wert TypeName
der Exception
-Eigenschaft des letzten Fehlers überprüfen. Um den Fehlertyp aus dem vorherigen Beispiel zu ermitteln, verwenden Sie diesen Befehl:
Das Ergebnis des obigen Codes würde ähnlich wie im Screenshot unten aussehen. Wie Sie sehen können, wird der Wert von TypeName
angezeigt – System.Management.Automation.ItemNotFoundException
.

Jetzt, da Sie den Fehlertyp kennen, den Sie abfangen müssen, ändern Sie den Code, um ihn spezifisch abzufangen. Wie Sie aus dem unten stehenden modifizierten Code sehen können, gibt es nun zwei Catch
-Blöcke. Der erste Catch
-Block fängt einen bestimmten Fehler ab (System.Management.Automation.ItemNotFoundException
). Im Gegensatz dazu enthält der zweite Catch
-Block die generische, alles abfangende Fehlermeldung.
Der folgende Screenshot zeigt die Ausgabe des oben modifizierten Codes.

Schlussfolgerung
In diesem Artikel haben Sie Fehler in PowerShell, deren Eigenschaften und wie Sie den spezifischen Fehlertyp bestimmen können, kennengelernt. Sie haben auch den Unterschied zwischen der Verwendung der Variablen $ErrorActionPreference
und dem PowerShell-Parameter ErrorAction
gelernt, wie PowerShell nicht-terminierende Fehler behandelt.
Sie haben auch gelernt, wie Sie die PowerShell-Blöcke Try Catch Finally
verwenden können, um Fehlerbehandlungen durchzuführen, egal ob für spezifische Fehler oder einen allgemeinen Ansatz.
Die in diesem Artikel gezeigten Beispiele demonstrieren nur die Grundlagen, wie die Try Catch Finally
-Blöcke funktionieren. Das Wissen, das Sie hoffentlich in diesem Artikel gewonnen haben, sollte Ihnen helfen, Fehlerbehandlungen in Ihren Skripten anzuwenden.