Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Kurzbeschreibung
Beschreibt die Arten von Fehlern in PowerShell und die Mechanismen für die Behandlung.
Lange Beschreibung
PowerShell unterscheidet drei Kategorien von Fehlern:
- Nicht beendete Fehler
- Fehler beim Beenden von Anweisungen
- Skriptbeendungsfehler
Das Verständnis der Unterscheidung ist für das Schreiben zuverlässiger Skripts und Module unerlässlich, da jede Kategorie unterschiedliche Standardverhalten aufweist und unterschiedliche Behandlungstechniken erfordert.
Darüber hinaus melden externe (systemeigene) Programme Fehler über Exitcodes, die PowerShell separat von seinem eigenen Fehlersystem nachverfolgt.
Fehlertypen
Nicht beendete Fehler
Ein nicht beendeter Fehler meldet ein Problem, beendet die Pipeline jedoch nicht. Der Befehl verarbeitet weiterhin nachfolgende Eingabeobjekte. Nicht beendete Fehler werden durch:
- Das
Write-ErrorCmdlet - Die
$PSCmdlet.WriteError()Methode in erweiterten Funktionen - Cmdlets, die bei einzelnen Eingabeobjekten auf wiederherstellbare Fehler stoßen
Standardmäßig zeigt PowerShell die Fehlermeldung an und setzt die Ausführung fort.
# Non-terminating error: the pipeline continues after the failure
'file1.txt', 'noSuchFile.txt', 'file3.txt' | ForEach-Object {
Get-Content $_ -ErrorAction Continue
}
In diesem Beispiel Get-Content wird ein nicht beendeter Fehler gemeldet noSuchFile.txt und anschließend die Verarbeitung file3.txtfortgesetzt.
Nicht beendete Fehler werden nicht ausgelöst oder trap standardmäßig nicht ausgelöstcatch.
Fehler beim Beenden von Anweisungen
Ein Anweisungsbeendfehler stoppt die ausführung der aktuellen Anweisung (Pipeline), die Ausführung wird jedoch bei der nächsten Anweisung im Skript fortgesetzt. Fehler beim Beenden von Anweisungen werden generiert durch:
- Die
$PSCmdlet.ThrowTerminatingError()Methode in erweiterten Funktionen und kompilierten Cmdlets - Modulfehler wie
CommandNotFoundException(Aufrufen eines nicht vorhandenen Befehls) undParameterBindingException(ungültige Parameterargumente) - .NET-Methodenaufrufe, die Ausnahmen auslösen, z. B.
[int]::Parse('abc')
# Statement-terminating error: Get-Item fails, but the next statement runs
Get-Item -Path 'C:\NoSuchFile.txt'
Write-Output 'This still runs'
Fehler beim Beenden von Anweisungen können von try/catch und trap.
Hinweis
.ThrowTerminatingError() den Parameter nicht konsultieren -ErrorAction (mit Ausnahme des Break Werts, der den Debugger eingibt).
$ErrorActionPreference
Gilt jedoch für Anweisungsbeendungsfehler über den Handler auf Anweisungsebene des Moduls. Kann z. B. einen Anweisungsbeendfehler unterdrücken, $ErrorActionPreference = 'SilentlyContinue' sodass das Skript bei der nächsten Anweisung fortgesetzt wird. Der -ErrorAction Parameter kann dies nicht tun. Ausführliche Informationen finden Sie unter The $ErrorActionPreference asymmetrisch.
Skriptbeendungsfehler
Ein Skriptbeendfehler entspannt den gesamten Aufrufstapel. Die Ausführung wird vollständig beendet, es sei denn, der Fehler wird von einem Block oder trap einer try/catch Anweisung abgefangen. Skriptbeendungsfehler werden von folgenden Elementen generiert:
- dem
throw-Schlüsselwort - Analysieren von Fehlern (Syntaxfehler, die verhindern, dass das Skript kompiliert wird)
- Nicht beendete Fehler werden von
-ErrorAction Stopoder$ErrorActionPreference = 'Stop'in nicht erweiterten Kontexten eskaliert. Weitere Informationen finden Sie unter "Funktionsweise der Eskalation". - Bestimmte kritische Motorfehler
# Script-terminating error: throw unwinds the call stack
function Test-Throw {
throw 'Critical failure'
Write-Output 'This never runs'
}
Test-Throw
Write-Output 'This never runs either (unless caught)'
Das throw Schlüsselwort generiert standardmäßig einen Skriptbeendfehler.
$ErrorActionPreference
Kann jedoch bei throw Festlegung auf SilentlyContinue oder Ignore. Beim Aufrufen einer erweiterten Funktion wird -ErrorAction SilentlyContinueder Parameter in einen bereichslokalen $ErrorActionPreference Wert übersetzt, sodass er auch innerhalb dieser Funktion unterdrückt wird throw .
Hinweis
Selbst bei $ErrorActionPreference = 'Ignore', ein throw unterdrücktes wird immer noch ein Eintrag in $Error. Der Ignore Wert verhindert nur die $Error Aufzeichnung für nicht beendete Fehler.
Von Bedeutung
Die Begriffe "Anweisung beenden" und "Skriptbeendung " beschreiben den Wirkungsbereich, nicht den Schweregrad des Fehlers. Ein Anweisungsbeendfehler stoppt eine Anweisung. Ein Skriptbeendfehler stoppt das gesamte Skript und seine Aufrufer. Beide können von try/catch.
Fehler des externen Programms
Externe (systemeigene) Programme nehmen nicht direkt am Fehlersystem von PowerShell teil. Sie melden einen Fehler über einen Nicht-Null-Ausgangscode, der von PowerShell in der $LASTEXITCODE automatischen Variablen gespeichert wird.
git clone https://example.com/nonexistent.git 2>$null
if ($LASTEXITCODE -ne 0) {
Write-Error "git failed with exit code $LASTEXITCODE"
}
Standardmäßig wird ein Nicht-Null-Exitcode aus einem systemeigenen Programm zurückgegeben:
- Legt auf fest
$?$false - Generiert kein
ErrorRecordIn$Error - Löst nicht aus
catchodertrap
PowerShell 7.3 hat die experimentelle Einstellungsvariable $PSNativeCommandUseErrorActionPreferencehinzugefügt, die in 7.4 zu einem stabilen Feature wurde. Wenn Sie diese Variable auf $truefestlegen, wird ein Nicht-Null-Beendigungscode einen nicht beendeten Fehler ausgegeben, dessen Meldung den spezifischen Beendigungscode (a NativeCommandExitException) angibt. Dieser Fehler berücksichtigt, sodass durch Festlegen des Fehlers $ErrorActionPreferenceder Fehler auf einen Skriptbeendungsfehler höher wird, der try/catchabgefangen werden kann.Stop
Fehlerstatusvariablen
PowerShell verwaltet mehrere automatische Variablen, die den aktuellen Fehlerstatus widerspiegeln.
$?
Enthält, $true ob der letzte Vorgang erfolgreich war und $false wenn ein Fehler (nicht beendet oder beendet) erzeugt wurde. Für systemeigene Befehle wird basierend auf dem Beendigungscode $? festgelegt: $true für Exit-Code 0, $false andernfalls.
Get-Item -Path 'C:\NoSuchFile.txt' 2>$null
$? # False
$Error
Ein ArrayList Objekt, das die neuesten Fehlerdatensätze speichert, wobei der letzte Fehler am Index 0aufgetreten ist. Die Liste enthält bis zu $MaximumErrorCount Einträge (Standard 256).
Alle Beendigungsfehler werden hinzugefügt $Error. Zum Beenden von Fehlern wird die Anzeige unterdrückt, Ignore aber weiterhin der Fehler in $Error. Alle nicht beendeten Vorgänge werden hinzugefügt $Error , es sei denn -ErrorAction Ignore , sie werden bei nicht beendeten Fehlern verwendet, was sowohl die Anzeige als auch die Aufzeichnung verhindert.
$LASTEXITCODE
Enthält den Exitcode des letzten systemeigenen Programms, das ausgeführt wurde. Ein Wert von 0 konventionell zeigt erfolglos an. Jeder Wert ungleich Null gibt einen Fehler an. Diese Variable ist nicht von PowerShell-Cmdlet-Fehlern betroffen.
Steuerelementfehlerverhalten
Der -ErrorAction allgemeine Parameter
Die -ErrorAction allgemeinen Parameterüberschreibungen $ErrorActionPreference für einen einzelnen Befehl. Sie steuert, wie PowerShell auf nicht beendete Fehler dieses Befehls reagiert.
| Wert | Verhalten |
|---|---|
Continue |
Anzeigen des Fehlers und Fortsetzen (Standard) |
SilentlyContinue |
Anzeige unterdrücken, hinzufügen $Error, fortfahren |
Ignore |
Anzeige unterdrücken und nicht hinzufügen $Error |
Stop |
Eskalieren zu einem Abbruchfehler (siehe Funktionsweise der Eskalation) |
Inquire |
Benutzer auffordern, eine Entscheidung zu treffen |
Break |
Geben Sie den Debugger ein. |
-ErrorAction ändert nicht das Verhalten von Fehlern, die von $PSCmdlet.ThrowTerminatingError(). Diese Fehler werden unabhängig von der Einstellung des Aufrufers immer von der Anweisung beendet.
Die $ErrorActionPreference Variable
Die $ErrorActionPreference Einstellungsvariable gilt für alle Befehle im aktuellen Bereich und untergeordneten Bereichen. Sie akzeptiert dieselben Werte wie -ErrorAction.
$ErrorActionPreference = 'Stop'
# All non-terminating errors in this scope now become terminating
Write-Error 'This now throws' # Generates ActionPreferenceStopException
Wenn -ErrorAction für einen Befehl angegeben wird, hat er Vorrang $ErrorActionPreference vor diesem Befehl.
Funktionsweise der Eskalation
Wenn -ErrorAction Stop oder $ErrorActionPreference = 'Stop' in Kraft ist, wandelt PowerShell nicht beendete Fehler mithilfe des folgenden Mechanismus in Beendigungsfehler um:
- Ein Cmdlet ruft
WriteError()intern auf, um einen nicht beendeten Fehler auszustrahlen. - Das Modul überprüft die effektive
ErrorActionEinstellung für den Befehl. - Da die Einstellung lautet
Stop, erstellt das Modul einenActionPreferenceStopException, der den ursprünglichen Fehlerdatensatz umschließt. - Wenn sie abgefangen
catchwerden, können Sie auf die ursprünglichen Fehlerinformationen zugreifen$_.Exception.ErrorRecord.
Der Umfang des eskalierten Fehlers hängt vom Kontext ab:
- In nicht erweiterten Skripts, Funktionen oder Skriptblöcken eskaliert die Einstellung
$ErrorActionPreference = 'Stop'auf einen Skriptbeendfehler . Der Fehler verteilt den Aufrufstapel. - In erweiterten Funktionen und Skriptblöcken (denen mit
[CmdletBinding()]) bleibt der Fehler anweisungsbeend. Die Ausführung wird nach dem Aufruf an der nächsten Anweisung fortgesetzt. - Das Übergeben
-ErrorAction Stopan eine erweiterte Funktion hat die gleiche Auswirkung wie die Einstellung$ErrorActionPreference = 'Stop'darin, da-ErrorActionsie in einen bereichslokalen$ErrorActionPreferenceWert übersetzt wird.
Eskalationsbeispiele
NICHT erweitert: Skriptbeendung ('after' wird NICHT gedruckt)
& { param() $ErrorActionPreference = 'Stop' Get-Item 'NoSuchPath' } 2>$null 'after'ADVANCED: Anweisungsbeendung ('after' DOES print)
& { [CmdletBinding()] param() $ErrorActionPreference = 'Stop'; Get-Item 'NoSuchPath' } 2>$null 'after'Ohne
-ErrorAction Stop: nicht beendet, wird "Catch" nicht ausgeführt.try { Write-Error 'This is non-terminating' Write-Output 'Execution continues' } catch { Write-Output "Caught: $_" # Not reached }Mit
-ErrorAction Stop: eskaliert bis zum Beendentry { Write-Error 'This becomes terminating' -ErrorAction Stop } catch { Write-Output "Caught: $_" # Reached }
Eskalierte Fehler können von ihrem ursprünglichen Ausnahmetyp abgefangen werden. Das Modul entpackt die ActionPreferenceStopException zugrunde liegende Ausnahme:
try {
Get-Item -Path 'C:\NoSuchFile.txt' -ErrorAction Stop
} catch [System.Management.Automation.ItemNotFoundException] {
Write-Output "File not found: $($_.Exception.Message)"
}
Die $ErrorActionPreference Asymmetrie
Der -ErrorAction Parameter und die $ErrorActionPreference Variable verhalten sich bei Beendigungsfehlern anders. Es ist wichtig, diese Asymmetrie zu verstehen:
-ErrorActionwirkt sich nur auf nicht beendete Fehler aus . Wenn ein Cmdlet aufruft$PSCmdlet.ThrowTerminatingError(), wird der-ErrorActionParameter ignoriert (mit AusnahmeBreakder Eingabe des Debuggers). Der Fehler wird immer ausgelöst.$ErrorActionPreferencewirkt sich sowohl auf Nichtbeendungs- als auch auf Anweisungsbeendungsfehler aus. Der Fehlerhandler auf Anweisungsebene des Moduls$ErrorActionPreferenceliest (nicht der-ErrorActionParameter) und kann einen Anweisungsbeendfehler unterdrücken, wenn der Wert istSilentlyContinueoderIgnore.
function Test-Asymmetry {
[CmdletBinding()]
param()
$er = [System.Management.Automation.ErrorRecord]::new(
[System.InvalidOperationException]::new('test error'),
'TestError',
[System.Management.Automation.ErrorCategory]::InvalidOperation,
$null
)
$PSCmdlet.ThrowTerminatingError($er)
}
# -ErrorAction SilentlyContinue does NOT suppress the error:
Test-Asymmetry -ErrorAction SilentlyContinue # Error is still thrown
# $ErrorActionPreference DOES suppress the error:
$ErrorActionPreference = 'SilentlyContinue'
Test-Asymmetry # Error is silently suppressed, script continues
$ErrorActionPreference = 'Continue'
Von Bedeutung
$ErrorActionPreferenceFehler, die auf " festgelegt" festgelegt truesindSuppressPromptInInterpreter, können nicht unterdrückt werden. Diese werden unabhängig von der Einstellungsvariable immer weitergegeben. Beispiele für diesen Fehlertyp sind:
-
ActionPreferenceStopExceptionaus-ErrorAction StopEskalation - Fehler innerhalb von PowerShell-Klassenmethoden
PipelineStoppedException
Fehler behandeln
try/catch/finally
Wird verwendet try/catch/finally , um Fehler beim Beenden von Anweisungen und Skripts zu behandeln. Wenn innerhalb eines try Blocks ein Fehler auftritt, sucht PowerShell nach einem übereinstimmenden catch Block. Der finally Block wird immer ausgeführt, unabhängig davon, ob ein Fehler aufgetreten ist.
try {
$result = Get-Content -Path 'data.txt' -ErrorAction Stop
}
catch [System.Management.Automation.ItemNotFoundException] {
Write-Warning 'Data file not found, using defaults.'
$result = 'default'
}
catch {
Write-Warning "Unexpected error: $_"
}
finally {
Write-Verbose 'Cleanup complete.' -Verbose
}
Innerhalb eines try Blocks legt das Modul ein internes Kennzeichen fest, das zu nicht beendeten Fehlern führt, die von -ErrorAction Stop oder $ErrorActionPreference = 'Stop' an den catch Block weitergegeben werden. Dies ist ein Designverhalten, kein Sonderfall.
Vollständige Syntaxdetails finden Sie unter about_Try_Catch_Finally.
trap
Die trap Anweisung behandelt Beendigungsfehler auf Der Bereichsebene. Wenn an einer beliebigen Stelle im eingeschlossenen Bereich ein Fehler auftritt, wird der trap Block ausgeführt.
-
Standard (nein
breakodercontinue): Der Fehler wird angezeigt, und die Ausführung wird bei der nächsten Anweisung nach der Anweisung fortgesetzt, die den Fehler verursacht hat. -
continuein the trap: Suppresses the error message and resumes at the next statement. -
breakin der Falle: Der Fehler wird an den übergeordneten Bereich weitergegeben.
trap [System.Management.Automation.CommandNotFoundException] {
Write-Warning "Command not found: $($_.TargetObject)"
continue
}
NonsenseCommand # Trap fires, execution continues
Write-Output 'This runs because the trap used continue'
Vollständige Syntaxdetails finden Sie unter about_Trap.
Melden von Fehlern in Funktionen und Skripts
Wählen Sie beim Schreiben von Funktionen und Skripts den Fehlerberichterstattungsmechanismus aus, der dem Schweregrad des Fehlers entspricht.
Nicht beendet – Verwendung Write-Error
Wird verwendet Write-Error , wenn die Funktion die Verarbeitung anderer Eingaben fortsetzen kann. Dies ist für Pipelinefunktionen geeignet, die mehrere Objekte verarbeiten und fehler bei einzelnen Elementen auftreten.
function Test-Path-Safe {
[CmdletBinding()]
param([Parameter(ValueFromPipeline)][string]$Path)
process {
if (-not (Test-Path $Path)) {
Write-Error "Path not found: $Path"
return
}
$Path
}
}
Hinweis
Verwenden Sie $PSCmdlet.WriteError() in erweiterten Funktionen (mit [CmdletBinding()]denen), statt Write-Error sicherzustellen, dass sie $? im Bereich des Aufrufers ordnungsgemäß festgelegt $false ist. Das Write-Error Cmdlet ist nicht immer richtig festgelegt $? .
Anweisungsbeendung – Verwenden $PSCmdlet.ThrowTerminatingError()
Wird verwendet $PSCmdlet.ThrowTerminatingError() , wenn die Funktion überhaupt nicht fortgesetzt werden kann, aber der Aufrufer sollte entscheiden, wie der Fehler behandelt werden soll. Dies ist der empfohlene Ansatz in erweiterten Funktionen.
function Get-Config {
[CmdletBinding()]
param([string]$Path)
if (-not (Test-Path $Path)) {
$er = [System.Management.Automation.ErrorRecord]::new(
[System.IO.FileNotFoundException]::new("Config file not found: $Path"),
'ConfigNotFound',
[System.Management.Automation.ErrorCategory]::ObjectNotFound,
$Path
)
$PSCmdlet.ThrowTerminatingError($er)
}
Get-Content $Path | ConvertFrom-Json
}
Nachdem der Fehler die Funktion verlassen hat, behandelt der Aufrufer sie standardmäßig als nicht beendeten Fehler. Der Anrufer kann eskalieren mit -ErrorAction Stop.
Skriptbeendung – Verwenden throw
Verwenden Sie diese Einstellung throw , wenn die Wiederherstellung nicht möglich ist und das gesamte Skript beendet werden soll.
$config = Get-Content 'config.json' -ErrorAction SilentlyContinue |
ConvertFrom-Json
if (-not $config) {
throw 'Cannot proceed without a valid configuration file.'
}
Welcher Mechanismus verwendet werden soll
- Bei der Verarbeitung mehrerer Eingaben, bei denen einige fehlschlagen, verwenden
Write-Erroroder$PSCmdlet.WriteError(). - Wenn die Funktion nicht fortgesetzt werden kann, verwenden
$PSCmdlet.ThrowTerminatingError()Sie die Funktion, und lassen Sie den Aufrufer entscheiden, wie sie behandelt werden soll. - Wenn das gesamte Skript sofort beendet werden muss, verwenden Sie
throw.
Zusammenfassung der Fehlertypen
In den folgenden Tabellen sind die Eigenschaften und Verhaltensweisen der verschiedenen Fehlertypen in PowerShell zusammengefasst.
Nicht beendeter Fehler
Nicht beendete Fehler können von Write-Error oder $PSCmdlet.WriteError().
| Merkmal | Beschreibung |
|---|---|
| Wirkungsbereich | Pipeline wird fortgesetzt |
Gefangen von catch |
Nein (es sei denn, eskaliert) |
Gefangen von trap |
Nein (es sei denn, eskaliert) |
Hinzugefügt zu $Error |
Ja (es sei denn Ignore, ) |
Legt auf fest $?$false |
Ja |
Betroffen von -ErrorAction |
Ja |
Betroffen von $ErrorActionPreference |
Ja |
Fehler beim Beenden der Anweisung
Fehler beim Beenden von Anweisungen können durch ThrowTerminatingError()Modulfehler, .NET-Methodenausnahmen oder -ErrorAction Stop in erweiterten Kontexten generiert werden.
| Merkmal | Beschreibung |
|---|---|
| Wirkungsbereich | Aktuelle Anweisung stoppt; Skript wird fortgesetzt |
Gefangen von catch |
Ja |
Gefangen von trap |
Ja |
Hinzugefügt zu $Error |
Ja |
Legt auf fest $?$false |
Ja |
Betroffen von -ErrorAction |
Nein (Break nur) |
Betroffen von $ErrorActionPreference |
Ja (kann unterdrückt werden) |
Skriptbeendungsfehler
Skriptbeendungsfehler können durch throwAnalysefehler oder -ErrorAction Stop in nicht erweiterten Kontexten generiert werden.
| Merkmal | Beschreibung |
|---|---|
| Wirkungsbereich | Anrufstapel entspannt sich |
Gefangen von catch |
Ja |
Gefangen von trap |
Ja |
Hinzugefügt zu $Error |
Ja |
Legt auf fest $?$false |
Ja |
Betroffen von -ErrorAction |
No |
Betroffen von $ErrorActionPreference |
throw: Ja (kann unterdrückt werden) |
Betroffen von $ErrorActionPreference |
Eskaliert: hängt vom Kontext ab |