💡 1. Nicht-terminierende vs. Terminierende Fehler
Das Fehlersystem von PowerShell unterscheidet zwei fundamentale Kategorien:
| Fehlerart | Verhalten | Wird von try/catch gefangen? |
|---|---|---|
Nicht-terminierend (z.B. Datei nicht gefunden bei Get-Item) |
Schreibt in den Error-Stream, Skript läuft einfach weiter. | ❌ NEIN! (Wird ignoriert) |
Terminierend (z.B. Syntaxfehler, throw, oder -ErrorAction Stop) |
Stoppt die Pipeline und wirft eine .NET-Exception. | ✅ JA! (Wird sofort abgefangen) |
Ein try/catch-Block fängt in PowerShell standardmäßig NUR terminierende Fehler ab! Um ein Cmdlet zwingend abfangbar zu machen, musst du -ErrorAction Stop anhängen oder am Skriptanfang $ErrorActionPreference = 'Stop' setzen!
🛡️ 2. Die try / catch / finally Architektur
Fange spezifische .NET-Exceptions gezielt ab und nutze finally, um Datenbankverbindungen, Sperren oder Dateien sicher aufzuräumen:
$ErrorActionPreference = 'Stop'
try {
# Kritische Operation mit -ErrorAction Stop:
$content = Get-Content -Path "C:\configs\app.json" -ErrorAction Stop
$json = $content | ConvertFrom-Json
}
catch [System.IO.FileNotFoundException] {
Write-Warning "Konfigurationsdatei nicht gefunden: $_"
}
catch [System.Management.Automation.ItemNotFoundException] {
Write-Warning "PowerShell-Pfad ungültig: $_"
}
catch {
# Universeller Fallback-Catch:
Write-Error "Unerwarteter Fehler: $($_.Exception.Message)"
}
finally {
# Wird IMMER ausgeführt – selbst bei Fehlern oder vorzeitigem return!
Write-Verbose "Aufräumarbeiten abgeschlossen."
}
try: Der Arbeitsbereich unter Beobachtung.
catch: Die Rettungsmannschaft, die je nach Fehlertyp (Brand, Rohrbruch) den passenden Notfallplan abarbeitet.
finally: Die Hausmeisterin, die garantiert immer das Licht ausschaltet und die Türen verriegelt – ganz egal, was während des Einsatzes passiert ist!
🔍 3. Das Fehler-Objekt ($_ / $Error[0])
Im catch-Block repräsentiert $_ ein vollwertiges ErrorRecord-Objekt mit tiefen Diagnose-Informationen:
catch {
$err = $_
$msg = $err.Exception.Message # Fehler-Text
$type = $err.Exception.GetType().FullName # Vollständiger .NET-Typ
$line = $err.InvocationInfo.ScriptLineNumber # Zeilennummer im Skript
# Eigenen terminierenden Fehler werfen:
throw "Fehler in Zeile $line: $msg"
}
📑 4. Cheat-Sheet: Error-Handling
| Mechanismus | Code | Bedeutung |
|---|---|---|
$ErrorActionPreference |
$ErrorActionPreference = 'Stop' |
Macht alle Skript-Fehler global terminierend. |
-ErrorAction |
Get-Item "file" -ErrorAction Stop |
Erzwingt terminierenden Fehler für einen Einzelbefehl. |
throw |
throw "Ungültiger Zustand" |
Löst manuell eine terminierende Exception aus. |
finally |
finally { $handle.Close() } |
Garantierter Cleanup-Block. |
🧠 Diagnostischer Selbst-Check
Überprüfe dein Verständnis zu PowerShell-Architektur, Pipeline-Mechanik und Best Practices mit gezieltem Feedback: