Einer der wichtigsten Teile eines guten PowerShell-Skripts ist die Fehlerbehandlung. Selbst im kürzesten Skript hilft die Möglichkeit, Fehler zu behandeln, sicherzustellen, dass ein unerwartetes Ereignis das System, an dem Sie arbeiten, nicht zerstört. Nehmen Sie das Beispiel unten. Jede Woche in unserem Beispielunternehmen (MyCompany.Com) Human Resources werden eine Liste hochladen, die uns mitteilt, wer Zugriff auf die Ausgabendatenbank haben soll., Wenn ein Name nicht in der Liste von HR enthalten ist, werden wir ihn aus der Gruppe entfernen und dieser Benutzer kann seine Ansprüche nicht mehr protokollieren:
Jetzt können Sie sehen, wo dies schief gehen wird. Eine Woche später kommt HR nicht zum Hochladen der Liste oder, genau wie wir auf die Liste zugreifen werden, stirbt der Dateiserver. Plötzlich löst PowerShell einen Fehler im Cmdlet Get-Content aus und die Variable $AuthorizedUser bleibt leer. Da unser Skript keine Fehler behandelt, wird es weiter ausgeführt und in sehr kurzer Zeit hat es jeden Benutzer aus unserer Ausgabengruppe entfernt., Ziemlich bald beginnen die wütenden Anrufe zu überschwemmen und das Leben wird etwas weniger glücklich. Der Weg, all dies zu vermeiden, besteht darin, die Fehler abzufangen und dann das Ereignis zu behandeln, das sie verursacht hat (was in diesem Fall darin besteht, das Skript anzuhalten und jemanden in HR anzuschreien).
Fehler beenden und nicht beenden
Eines der wichtigsten Dinge, die Sie beim Abfangen von Fehlern wissen sollten, ist, dass standardmäßig nur bestimmte Fehler abgefangen werden können. Fehler gibt es in zwei Arten-Beenden und Nicht beenden. Ein Abschlussfehler ist ein Fehler, der eine Funktion oder Operation anhält., Wenn Sie einen Syntaxfehler machen oder kein Speicher mehr vorhanden ist, ist dies ein Abschlussfehler. Abschließende Fehler können abgefangen und behandelt werden. Nicht abschließende Fehler ermöglichen es Powershell, fortzufahren und stammen normalerweise von Cmdlets oder anderen verwalteten Situationen. Unter normalen Umständen können sie nicht von Try-Catch-Finally gefangen werden. Der Get-Content-Fehler im obigen Beispiel ist ein nicht abschließender Fehler.
Behandeln von nicht abschließenden Fehlern als Beenden
Wie fangen Sie einen nicht abschließenden Fehler ab? Grundsätzlich sagen Sie PowerShell, es als beendet zu behandeln. Verwenden Sie dazu den Parameter ErrorAction., Jedes PowerShell-Cmdlet unterstützt ErrorAction. Wenn Sie-ErrorAction Stop am Ende eines Cmdlets angeben, stellen Sie sicher, dass alle Fehler, die es auslöst, als beendet behandelt werden und abgefangen werden können. In unserem obigen Beispiel ändern wir unsere Get-Content-Zeile in:
$AuthorizedUsers= Get-Content \\ FileServer\HRShare\UserList.txt -ErrorAction Stop
Alle Fehler werden als beendet behandelt
Es ist auch möglich, alle Fehler mit der Variablen ErrorActionPreference als Beendet zu behandeln. Sie können dies entweder für das Skript tun, mit dem Sie arbeiten, oder für die gesamte PowerShell-Sitzung. Um es in einem Skript festzulegen, machen Sie die erste Zeile $ErrorActionPreference = Stop., Um es für die Sitzung festzulegen, geben Sie $ErrorActionPreference = Stop in der PowerShell-Konsole ein.
Abfangen eines Abschlussfehlers
Sobald Sie sichergestellt haben, dass der Fehler, den Sie abfangen möchten, als beendet behandelt wird, können Sie einen Try Catch-Block um den Befehl (oder die Befehle) erstellen, der den Fehler verursachen könnte. Die erste Stufe besteht darin, den Abschnitt Ihres Skripts zu umgeben, der den Fehler möglicherweise mit einem Try-Block auslöst. In unserem Beispiel wird die Zeile Get-Content:
Try{ $AuthorizedUsers= Get-Content \\ FileServer\HRShare\UserList.txt -ErrorAction Stop}
Unmittelbar nach dem Try-Block müssen Sie einen Catch-Block platzieren, um den Fehler zu beheben., Auf den Catch-Block wird nur zugegriffen, wenn ein Abschlussfehler auftritt, andernfalls wird er ignoriert. In unserem Beispiel senden wir einem Administrator eine E-Mail, um festzustellen, dass ein Fehler aufgetreten ist, und halten das Skript dann an. Unsere Get-Content Zeile lautet jetzt:
Zugriff auf den Fehlerdatensatz
Sobald Sie sich in einem Catch-Block befinden, können Sie auf den Fehlerdatensatz zugreifen, der in der aktuellen Objektvariablen $_gespeichert ist. Fehlerdatensätze haben verschiedene nützliche Eigenschaften, aber die wichtigste, auf die Sie zugreifen möchten, ist $_.Ausnahme., Ausnahmen sind das, womit wir es hier wirklich zu tun haben, wenn wir Fehler abfangen und behandeln – Ausnahmen sind das unerwartete Ereignis, das den Fehler verursacht hat (der Fehlerdatensatz selbst ist eigentlich nur ein Wrapper, um die Ausnahme dem PowerShell-Benutzer darzustellen). Es ist die Ausnahme, die wir abfangen, und die Ausnahme, die alle wirklich nützlichen Informationen über das Problem enthält. Wenn es ein weiteres zugrunde liegendes Problem gab, das unsere Ausnahme verursacht hat, wird es auch bei $_aufgezeichnet.Ausnahme.innerexception (und so weiter-die nächste zugrunde liegende Ausnahme wird bei $_gespeichert.Ausnahme.innerexception.,innerexception usw.). Für die Zwecke unseres Beispiels werden wir $_verwenden.Ausnahme, um einige zusätzliche Informationen in unsere Benachrichtigungs-E-Mail mit dem $_einzufügen.Ausnahme.Nachricht und $_.Ausnahme.ItemName properties:
Catching Specific Exceptions
Wie unser Beispiel zeigt, fangen wir jetzt alle Fehler ab, die beim Lesen der Datei auftreten, und behandeln sie alle auf die gleiche Weise. Sie können jedoch bestimmte Ausnahmen abfangen und anders behandeln, aber – und es ist ein großes aber – nur, wenn der ursprüngliche Fehler beendet wird., Da das Cmdlet Get-Content nicht abschließende Fehler auslöst (die wir nur mit ErrorAction als Beendigung behandelt haben), können wir die verschiedenen Ausnahmen, die das Cmdlet möglicherweise auslöst, nicht speziell abfangen. Dies ist eine Funktion von PowerShell und gilt für nicht abschließende Fehler, unabhängig von der ErrorActionPreference und kann nicht geändert werden. Dennoch können wir uns mit anderen abschließenden Ausnahmen befassen, z. B. einem Speicherfehler, der während des Lesevorgangs auftreten kann. Für die Zwecke dieses Beispiels werden wir das tun.,
Sie fangen bestimmte Abschlussfehler ab, indem Sie den Ausnahmenamen unmittelbar nach dem Schlüsselwort Catch angeben. In unserem Beispiel wollen wir ein System fangen.OutOfMemory Ausnahme und, wenn wir einen bekommen, wird den No-Nonsense-Ansatz des Neustarts des Computers sofort nehmen. Wir werden auch einen allgemeinen catch-Block nach unserem Block „Datei nicht gefunden“ einfügen, um alle anderen Ausnahmen abzufangen:
Schließlich ist mit Finally
Der letzte Teil von Try Catch Finally der Finally Block. Dies muss unmittelbar nach dem Catch-Block definiert werden und wird jedes Mal ausgeführt, unabhängig davon, ob ein Fehler aufgetreten ist oder nicht., Auf diese Weise können Sie Aktionen ausführen, die ausgeführt werden müssen, unabhängig davon, ob eine Operation erfolgreich ist oder fehlschlägt. In unserem Beispiel protokollieren wir, dass versucht wurde, eine Datei zu lesen. Unsere Get-Content-Zeile sieht jetzt so aus: