Zum Inhalt springen

Fehlerbehandlung

Core
Lernziele
  • Terminierende und nicht-terminierende Fehler unterscheiden
  • try/catch/finally korrekt einsetzen
  • Fehlerinformationen auslesen ($_, $Error)

Robuste Skripte rechnen damit, dass etwas schiefgeht: Datei fehlt, Server nicht erreichbar, Zugriff verweigert. Fehlerbehandlung bestimmt, was dann passiert.

PowerShell kennt nicht-terminierende Fehler (Standard bei Cmdlets) und terminierende Fehler.

Terminal-Fenster
Get-Content -Path C:\Kurs\gibt-es-nicht.txt
Write-Output "Ich laufe trotzdem weiter."

Das Cmdlet meldet einen Fehler in Rot, das Skript macht aber weiter. Das ist ein nicht-terminierender Fehler.

Terminal-Fenster
try {
Get-Content -Path C:\Kurs\gibt-es-nicht.txt -ErrorAction Stop
}
catch {
Write-Warning "Datei konnte nicht gelesen werden: $($_.Exception.Message)"
}

Mit -ErrorAction Stop wird der Fehler terminierend. Innerhalb von catch steht der Fehler in $_.

-ErrorAction Wirkung
Continue Standard: Fehler anzeigen, weitermachen
Stop Fehler wird terminierend, catch greift
SilentlyContinue Fehler unterdrücken und weitermachen
Ignore Fehler vollständig ignorieren (nicht in $Error)

Für ein ganzes Skript setzt du $ErrorActionPreference = 'Stop' an den Anfang. Mach das bewusst und nicht aus Gewohnheit.

Terminal-Fenster
try {
$inhalt = Get-Content -Path $Pfad -ErrorAction Stop
}
catch {
Write-Warning "Fehler: $($_.Exception.Message)"
}
finally {
Write-Verbose "Aufräumen, läuft immer."
}

finally läuft immer, mit oder ohne Fehler. Es ist der Ort für Aufräumarbeiten (Verbindung schließen, Transcript beenden).

Welche Art Fehler ist aufgetreten? Frag das Objekt:

Terminal-Fenster
try {
Get-Item -Path C:\Kurs\gibt-es-nicht.txt -ErrorAction Stop
}
catch {
$_.Exception.GetType().FullName
}

Das Ergebnis (System.Management.Automation.ItemNotFoundException) setzt du in den catch ein:

Terminal-Fenster
try {
Get-Item -Path C:\Kurs\gibt-es-nicht.txt -ErrorAction Stop
}
catch [System.Management.Automation.ItemNotFoundException] {
Write-Warning "Pfad existiert nicht."
}
catch {
Write-Warning "Unerwarteter Fehler: $($_.Exception.Message)"
}
Terminal-Fenster
if (-not (Test-Path $Pfad)) {
throw "Eingabedatei fehlt: $Pfad"
}

throw erzeugt einen terminierenden Fehler. In Funktionen nutzt du für Parameterfehler besser Write-Error oder Parametervalidierung.

PowerShell sammelt Fehler in $Error. Der neueste steht vorn:

Terminal-Fenster
$Error[0]
$Error[0] | Format-List * -Force
  • Fange Fehler dort, wo du sinnvoll reagieren kannst.
  • Gib verständliche Meldungen aus: Was wurde versucht, was ist schiefgegangen?
  • Verschlucke Fehler nicht stillschweigend (SilentlyContinue überall ist ein Anti-Pattern).
  • Räume im finally auf.
  • Logge Fehler (siehe Logging und Transcripts).
  • try/catch fängt nur terminierende Fehler. -ErrorAction Stop macht Cmdlet-Fehler terminierend.
  • $_ im catch enthält die Fehlerinformation. finally läuft immer.
  • Den Fehlertyp liest du mit $_.Exception.GetType().FullName aus.