Wie der Name schon sagt, ist PowerShell viel leistungsfähiger als die Standard-Windows-Eingabeaufforderung. Mit dieser Leistungsfähigkeit steigt auch die Wahrscheinlichkeit, dass es zu verwirrenden Fehlern kommt. Wenn Ihr Skript plötzlich fehlschlägt, wissen Sie möglicherweise nicht, wo Sie anfangen sollen, nach dem Fehler zu suchen. An dieser Stelle kommt die Fehlerbehandlung von PowerShell ins Spiel.
Wenn Sie mit anderen Sprachen vertraut sind, kennen Sie wahrscheinlich die Grundlagen der Fehlerbehandlung, aber es gibt einige PowerShell-spezifische Aspekte, die Sie kennen müssen. Die Fehlerbehandlung in PowerShell besteht aus vier Teilen: dem Fehleraktionsparameter, Try/Catch-Blöcken, dem Fehlervariablenparameter und der Protokollierung.
PowerShell-Fehlerbehandlung auf die einfache Art
Der erste Schritt bei der Behandlung von PowerShell-Fehlern besteht darin, etwas zu behandeln, das Ihr Skript in seinem Verlauf stoppt. Wenn sich der Fehler nicht auf den Rest des Skripts auswirkt, ist es vielleicht am besten, PowerShell anzuweisen, Fehler zu ignorieren und weiterzumachen.
Andererseits ist es nicht immer klar, wann ein bestimmtes Cmdlet einen Beendigungsfehler auslöst. Einige Cmdlets geben einen Fehler zurück, halten Ihr Skript aber nicht an. Dies kann dazu führen, dass Sie auf die Fertigstellung Ihres Skripts warten, während es Unsinn ausgibt.
An dieser Stelle kommt der Parameter -ErrorAction ins Spiel. Sie verwenden ihn, um ein Cmdlet zu zwingen, den Fehler so zu behandeln, wie Sie es wünschen. Wenn Sie ein vorhandenes Skript ändern, hängen Sie ihn an das Ende der Cmdlet-Zeile an.
Get-ChildItem -Path "~\Documents\*.jpg" -Recurse -ErrorAction Stop
Wenn Sie das Cmdlet „Get-ChildItem“ allein verwenden, nützt Ihnen dieser Fehler natürlich nicht viel. Wenn Sie jedoch etwas mit den Daten machen wollen, wäre es gut, das Skript anzuhalten, damit Sie wissen, dass die Suche fehlgeschlagen ist und warum. Wenn Sie mehrere Suchvorgänge durchführen, können Sie auch den Parameter von Stop in SilentlyContinue ändern, damit das Skript fortgesetzt wird, wenn eine Suche fehlschlägt. Wenn Sie den Fehler sehen wollen, können Sie stattdessen Continue als Parameter verwenden.
Get-ChildItem -Path "~\Documents\*.jpg" -Recurse -ErrorAction SilentlyContinue
Wenn Sie lieber steuern möchten, was bei jeder Ausführung Ihres Skripts passiert, können Sie den Parameter in Inquire ändern. Wenn Ihr Cmdlet auf ein Problem stößt, gibt es Optionen: Ja, Ja für alle, Befehl anhalten, Anhalten oder Hilfe.
Diese Option ist etwas flexibler, führt aber dazu, dass Ihr Skript bei Fehlern auf Ihre Eingabe wartet. Das ist in Ordnung, wenn Sie PowerShell verwenden, um eine E-Mail oder eine andere einfache Aufgabe zu senden, aber es ist vielleicht nicht das, was Sie wollen, wenn Sie einen langen Prozess über Nacht laufen lassen.
PowerShell-Fehlerbehandlung auf leistungsstarke Weise
Der ErrorAction-Parameter behandelt Ihre Fehler auf unkomplizierte Weise. Wenn Sie jedoch etwas mehr Kontrolle über Fehler haben möchten, hat PowerShell immer noch eine Lösung für Sie. Mit Try/Catch können wir jetzt das Skript verzweigen, wenn Cmdlets einen Fehler zurückgeben.
Wie der Name schon sagt, besteht Try/Catch aus zwei Teilen. (Technisch gesehen gibt es noch einen dritten Teil, aber dazu kommen wir gleich.) Der erste Teil ist der Try-Abschnitt. In diesem Abschnitt führen Sie Ihren normalen Code aus. Sie verwenden weiterhin den Parameter -ErrorAction, der jedoch nur auf Stop gesetzt werden kann. Mit dieser Markierung wird sichergestellt, dass Ihr Cmdlet den Catch auslöst, auch wenn es keinen abschließenden Fehler gibt.
Try{
Get-Process "Cortana" -ErrorAction Stop
}
Try kann auch verhindern, dass andere Cmdlets ausgeführt werden, wenn die Suche fehlschlägt. In diesem Fall, wenn Sie die Get-Process-Ergebnisse an Stop-Process senden, verhindert eine fehlgeschlagene Suche die Ausführung des zweiten Cmdlets.
Wenn Sie nun einen Try-Block mit Cmdlets erstellt haben, was wollen Sie dann tun, wenn er fehlschlägt? Mithilfe der Catch-Hälfte werden Sie dies definieren.
Catch{
Write-Host "Process Not Found"
}
Wie beim ErrorAction-Parameter ist Catch vor allem dann nützlich, wenn Sie etwas etwas Komplexeres tun, als einen einfachen Fehler zu melden. (Im obigen Beispiel wird der Fehler durch die Verwendung des Anwendungsnamens und nicht des Prozessnamens erzwungen). Stellen Sie also sicher, dass Sie mit dem Try-Block spielen, um eine Suche/Aktion zu erstellen, die Sie benötigen. Sie können den Catch-Block für Ihr Skript verwenden, um eine E-Mail zu erhalten, wenn es fehlschlägt.
Der dritte Teil ist nützlich, wenn Sie möchten, dass etwas unabhängig davon ausgeführt wird, ob Ihr Cmdlet erfolgreich ist oder nicht. Hierfür können Sie den Finally-Block verwenden. Diesen fügen Sie nach Try und Catch ein und protokollieren, wenn ein Abschnitt Ihres Skripts endet.
Die Fehlervariable und die Protokollierung
Ihr Skript steuert nun, wie es mit Fehlern umgeht und wie es auf sie reagiert. Sie können es als geplante Aufgabe verwenden oder es zumindest ausführen, wenn Sie nicht an Ihrem Schreibtisch sitzen. Doch wie können Sie ein fehlgeschlagenes Skript untersuchen? Mit dem Parameter -ErrorVariable werden die Fehler Ihres Cmdlets in eine benutzerdefinierte Variable geschrieben.
Dies ist eine Alternative zur Systemvariable $Error, die alle Fehler der aktuellen Sitzung enthält.
Ihr Cmdlet muss ein wenig länger werden. Definieren Sie zunächst eine Variable, für das Beispiel reicht etwa $SearchError. Wenn Sie SearchError im Parmeter ErrorVariable aufrufen, verwenden Sie das Dollarzeichen nicht.
Auch wenn Sie eine Variable aufrufen, die Sie erstellt haben, rufen Sie sie aufgrund der Funktionsweise des Parameters ohne das Dollarzeichen auf. Dann fügen Sie das am Ende der Zeile hinzu.
Get-ChildItem -Path "~\Documents\*.jpg" -Recurse -ErrorAction Continue -ErrorVariable SearchError
Wenn Sie dem Variablennamen ein + voranstellen, können Sie die Variable ergänzen, anstatt sie ganz zu ersetzen. Dadurch erhalten Sie das gleiche Verhalten wie bei der globalen Fehlervariable. Stattdessen können Sie diese Ausgabe und Try/Catch verwenden, um eine benutzerdefinierte Ausgabe zu schreiben, und diese mit einem Zeitstempel versehen.
Damit dies funktioniert, erstellen Sie eine Textdatei, direkt nachdem Sie die Fehlervariable gesetzt haben. Tun Sie dies mit dem Cmdlet „New-Item“. Möglicherweise möchten Sie die Option Inquire für den Parameter ErrorAction verwenden. Damit können Sie einem vorhandenen Protokoll hinzufügen, wenn das Cmdlet „New-Item“ fehlschlägt.
$SearchLog = New-Item "~\SearchLog.txt" -type file -ErrorAction Inquire
Wenn Sie nun Ihren Try/Catch-Block erstellen, können Sie den Catch verwenden, um in einer Textdatei zu protokollieren. Sie verwenden Get-Date, um den Zeitstempel zu erstellen. Die Formatierung kann knifflig sein, daher sollten Sie sie aus dem Beispiel übernehmen.
Try{
Get-ChildItem -Path "~\Documents\*.jpg" -Recurse -ErrorAction Stop -ErrorVariable SearchError
}
Catch{
Add-Content -Path $SearchLog -Value "$(Get-Date -Format dd-MM-yy-hh_mm_ss) Files not found returned error: $SearchError"
}
Wiederholen Sie dies nach Bedarf für alle Ihre Cmdlets, und Sie haben jetzt ein schönes Protokoll aller Fehler. Wenn Sie erfolgreich ausgeführte Cmdlets protokollieren möchten, können Sie am Ende des Try-Blocks einen ähnlichen Add-Content hinzufügen.
Diese Protokollierung wird nur ausgeführt, wenn Ihr Cmdlet Try erfolgreich ist. Sie können dann Ihre Fehler und Erfolge mit Zeitstempeln protokollieren. Durch die Protokollierung wissen Sie nun, was Ihr Skript getan hat, ob es erfolgreich war oder nicht.
PowerShell ist nicht die einzige Option
PowerShell ist zwar ein praktisches Tool für viele Windows-Aufgaben, aber es kann schwierig sein, es zu lernen. Es ist auch nicht für alles geeignet. Wenn Sie eine Systemwartung auf Ihrem Computer durchführen oder die Integrität einer Datei überprüfen, ist PowerShell sehr praktisch. Wenn Sie hingegen ein Skript zum Herunterladen von Dateien aus dem Internet oder eine allgemeinere Aufgabe ausführen möchten, haben Sie andere Möglichkeiten.
Wenn Sie zum Beispiel von einem Unix- oder Linux-Hintergrund kommen, sind Sie vielleicht mit der Bash-Shell besser vertraut. Dank des Windows-Subsystems für Linux können Sie Bash und andere Linux-Tools jetzt problemlos auf Ihrem Windows 10-Computer verwenden. Wenn sich das für Sie perfekt anhört, sollten Sie sich unsere Anleitung ansehen, wie Sie die Bash-Shell unter Windows 10 zum Laufen bringen.
Kris Wouk ist Musiker, Autor und wie auch immer man es nennt, wenn jemand Videos für das Web macht. Solange er denken kann, ist er ein Technik-Enthusiast. Er hat definitiv Lieblings-Betriebssysteme und -Geräte, benutzt aber trotzdem so viele andere wie möglich, um auf dem Laufenden zu bleiben.
Mehr von Kris Wouk