Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Kort beskrivning
Beskriver typerna av fel i PowerShell och mekanismerna för att hantera dem.
Lång beskrivning
PowerShell särskiljer tre felkategorier:
- Icke-avslutande fel
- Instruktionsslutfel
- Skriptslutfel
Att förstå skillnaden är viktigt för att skriva tillförlitliga skript och moduler, eftersom varje kategori har olika standardbeteende och kräver olika hanteringstekniker.
Dessutom rapporterar externa (inbyggda) program fel via slutkoder, som PowerShell spårar separat från sitt eget felsystem.
Typer av fel
Icke-avslutande fel
Ett icke-avslutande fel rapporterar ett problem men stoppar inte pipelinen. Kommandot fortsätter att bearbeta efterföljande indataobjekt. Icke-avslutande fel genereras av:
- Cmdlet
Write-Error - Metoden
$PSCmdlet.WriteError()i avancerade funktioner - Cmdletar som påträffar återställningsbara fel på enskilda indataobjekt
Som standard visar PowerShell felmeddelandet och fortsätter körningen.
# Non-terminating error: the pipeline continues after the failure
'file1.txt', 'noSuchFile.txt', 'file3.txt' | ForEach-Object {
Get-Content $_ -ErrorAction Continue
}
I det här exemplet Get-Content rapporterar ett icke-avslutande fel för noSuchFile.txt och fortsätter sedan bearbetningen file3.txt.
Icke-avslutande fel utlöses catchinte eller trap som standard.
Instruktionsslutfel
Ett instruktionsslutfel hindrar den aktuella instruktionen (pipelinen) från att köras, men körningen fortsätter vid nästa instruktion i skriptet. Instruktionsslutfel genereras av:
- Metoden
$PSCmdlet.ThrowTerminatingError()i avancerade funktioner och kompilerade cmdletar - Motorfel som
CommandNotFoundException(anropar ett kommando som inte finns) ochParameterBindingException(ogiltiga parameterargument) - .NET-metodanrop som utlöser undantag, till exempel
[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'
Instruktionsslutfel kan fångas av try/catch och trap.
Anmärkning
.ThrowTerminatingError() läser inte parametern -ErrorAction (förutom värdet Break som anger felsökaren).
Gäller dock $ErrorActionPreference för instruktionsslutfel via motorns instruktionsnivåhanterare. Kan till exempel $ErrorActionPreference = 'SilentlyContinue' förhindra ett instruktionsslutfel så att skriptet fortsätter vid nästa instruktion. Parametern -ErrorAction kan inte göra detta. Mer information finns i asymmetrin $ErrorActionPreference.
Skriptslutfel
Ett skriptslutfel avbryter hela anropsstacken. Körningen stoppas helt om inte felet fångas av ett block eller trap en try/catch -instruktion. Skriptslutfel genereras av:
- Nyckelordet
throw - Parsa fel (syntaxfel som förhindrar att skriptet kompileras)
- Icke-avslutande fel eskaleras av
-ErrorAction Stopeller$ErrorActionPreference = 'Stop'i icke-avancerade kontexter. Mer information finns i Så här fungerar eskalering. - Vissa kritiska motorfel
# 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)'
Nyckelordet throw genererar ett skriptslutfel som standard.
Kan dock $ErrorActionPreference utelämna throw när det är inställt på SilentlyContinue eller .Ignore När du anropar en avancerad funktion med -ErrorAction SilentlyContinueöversätts parametern till ett omfångslokalt $ErrorActionPreference värde, så den undertrycker throw även inuti den funktionen.
Anmärkning
Även med $ErrorActionPreference = 'Ignore', en throw som ignoreras registrerar fortfarande en post i $Error. Värdet Ignore förhindrar $Error endast registrering för icke-avslutande fel.
Viktigt!
Termerna statement-terminating och script-terminating beskriver effektens omfattning, inte felets allvarlighetsgrad. Ett instruktionsslutfel stoppar en instruktion. Ett skriptslutfel stoppar hela skriptet och dess anropare. Båda kan fångas av try/catch.
Externa programfel
Externa (interna) program deltar inte direkt i PowerShells felsystem. De rapporterar fel via en slutkod som inte är noll, som PowerShell lagrar i den $LASTEXITCODE automatiska variabeln.
git clone https://example.com/nonexistent.git 2>$null
if ($LASTEXITCODE -ne 0) {
Write-Error "git failed with exit code $LASTEXITCODE"
}
Som standard en slutkod som inte är noll från ett internt program:
- Anger
$?till$false - Genererar inte en
ErrorRecordi$Error - Utlöses
catchinte ellertrap
PowerShell 7.3 lade till den experimentella inställningsvariabeln $PSNativeCommandUseErrorActionPreference, som blev en stabil funktion i 7.4. När du anger den här variabeln till $trueorsakar det en slutkod som inte är noll för att generera ett icke-avslutande fel vars meddelande anger den specifika slutkoden (a NativeCommandExitException). Det här felet respekterar $ErrorActionPreference, så om du ställer in det på Stop befordras felet till ett skriptslutfel som kan fångas med/trycatch .
Feltillståndsvariabler
PowerShell har flera automatiska variabler som återspeglar det aktuella feltillståndet.
$?
Innehåller $true om den senaste åtgärden lyckades och $false om det uppstod något fel (icke-avslutande eller avslutande). För interna kommandon $? anges baserat på slutkoden: $true för slutkod 0, $false annars.
Get-Item -Path 'C:\NoSuchFile.txt' 2>$null
$? # False
$Error
En ArrayList som lagrar de senaste felposterna, med det senaste felet vid index .0 Listan innehåller upp till $MaximumErrorCount poster (standard 256).
Alla avslutande fel läggs till i $Error. För att avsluta fel Ignore undertrycker visning men registrerar fortfarande felet i $Error. Alla icke-avslutande läggs till $Error om inte -ErrorAction Ignore används vid icke-avslutande fel, vilket förhindrar både visning och inspelning.
$LASTEXITCODE
Innehåller slutkoden för det senaste interna programmet som kördes. Ett värde för 0 konventionellt indikerar framgång. Alla värden som inte är noll indikerar fel. Den här variabeln påverkas inte av PowerShell-cmdlet-fel.
Kontrollera felbeteende
Den -ErrorAction gemensamma parametern
Den -ErrorAction vanliga parametern åsidosätter $ErrorActionPreference för ett enda kommando. Den styr hur PowerShell svarar på icke-avslutande fel från det kommandot.
| Värde | Beteende |
|---|---|
Continue |
Visa felet och fortsätt (standard) |
SilentlyContinue |
Ignorera visning, lägg till i $Error, fortsätt |
Ignore |
Ignorera visning och lägg inte till i $Error |
Stop |
Eskalera till ett avslutande fel (se Så här fungerar eskalering) |
Inquire |
Fråga användaren om ett beslut |
Break |
Ange felsökningsprogrammet |
-ErrorAction ändrar inte beteendet för fel som genereras av $PSCmdlet.ThrowTerminatingError(). Dessa fel är alltid instruktionsslutande oavsett uppringarens önskemål.
Variabeln $ErrorActionPreference
Inställningsvariabeln $ErrorActionPreference gäller för alla kommandon i det aktuella omfånget och underordnade omfång. Den accepterar samma värden som -ErrorAction.
$ErrorActionPreference = 'Stop'
# All non-terminating errors in this scope now become terminating
Write-Error 'This now throws' # Generates ActionPreferenceStopException
När -ErrorAction har angetts för ett kommando har det företräde framför $ErrorActionPreference det kommandot.
Så här fungerar eskalering
När -ErrorAction Stop eller $ErrorActionPreference = 'Stop' är i kraft konverterar PowerShell icke-avslutande fel till avslutande fel med hjälp av följande mekanism:
- En cmdlet anropar
WriteError()internt för att generera ett icke-avslutande fel. - Motorn kontrollerar den effektiva
ErrorActioninställningen för kommandot. - Eftersom inställningen är
Stopskapar motorn enActionPreferenceStopExceptionsom omsluter den ursprungliga felposten. - Om den fångas av
catchär den ursprungliga felinformationen tillgänglig via$_.Exception.ErrorRecord.
Omfattningen för det eskalerade felet beror på kontexten:
- I icke-avancerade skript, funktioner eller skriptblock eskaleras inställningen
$ErrorActionPreference = 'Stop'till ett skriptslutfel . Felet sprider upp anropsstacken. - I avancerade funktioner och skriptblock (de med
[CmdletBinding()]) förblir felet instruktionsslutande. Körningen fortsätter vid nästa instruktion efter anropet. - Att skicka
-ErrorAction Stoptill en avancerad funktion har samma effekt som inställningen$ErrorActionPreference = 'Stop'i den, eftersom-ErrorActiondet översätts till ett omfångslokalt$ErrorActionPreferencevärde.
Eskaleringsexempel
Icke-avancerat: skriptavslutande ("efter" skrivs INTE ut)
& { param() $ErrorActionPreference = 'Stop' Get-Item 'NoSuchPath' } 2>$null 'after'AVANCERAT: instruktionsavslutande ("efter" SKRIVS UT)
& { [CmdletBinding()] param() $ErrorActionPreference = 'Stop'; Get-Item 'NoSuchPath' } 2>$null 'after'Utan
-ErrorAction Stop: icke-avslutande körs inte catchtry { Write-Error 'This is non-terminating' Write-Output 'Execution continues' } catch { Write-Output "Caught: $_" # Not reached }Med
-ErrorAction Stop: eskalerad till avslutandetry { Write-Error 'This becomes terminating' -ErrorAction Stop } catch { Write-Output "Caught: $_" # Reached }
Eskalerade fel kan fångas av den ursprungliga undantagstypen. Motorn skriver upp ActionPreferenceStopException för att hitta det underliggande undantaget:
try {
Get-Item -Path 'C:\NoSuchFile.txt' -ErrorAction Stop
} catch [System.Management.Automation.ItemNotFoundException] {
Write-Output "File not found: $($_.Exception.Message)"
}
Asymmetrin $ErrorActionPreference
Parametern -ErrorAction och variabeln $ErrorActionPreference beter sig annorlunda med avslutande fel. Det är viktigt att förstå den här asymmetrin:
-ErrorActionpåverkar endast icke-avslutande fel. När en cmdlet anropar$PSCmdlet.ThrowTerminatingError()ignoreras parametern-ErrorAction(förutomBreak, som anger felsökaren). Felet genereras alltid.$ErrorActionPreferencepåverkar både icke-avslutande och instruktionsslutande fel. Motorns felhanterare på instruktionsnivå läser$ErrorActionPreference(inte parametern-ErrorAction) och kan utelämna ett instruktionsslutfel när värdet ärSilentlyContinueellerIgnore.
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'
Viktigt!
$ErrorActionPreference kan inte utelämna fel som har SuppressPromptInInterpreter angetts till true. Dessa sprids alltid oavsett inställningsvariabeln. Exempel på den här typen av fel är:
-
ActionPreferenceStopExceptionfrån-ErrorAction Stopeskalering - Fel i PowerShell-klassmetoder
PipelineStoppedException
Hantering av fel
try/catch/finally
Använd try/catch/finally för att hantera instruktionsterminerings- och skriptslutfel. När ett fel inträffar i ett try block söker PowerShell efter ett matchande catch block. Blocket finally körs alltid, oavsett om ett fel uppstod eller inte.
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
}
I ett try block anger motorn en intern flagga som gör att icke-avslutande fel eskaleras av -ErrorAction Stop eller $ErrorActionPreference = 'Stop' sprids till catch blocket. Detta är utformat beteende, inte ett specialfall.
Fullständig syntaxinformation finns i about_Try_Catch_Finally.
trap
Instruktionen trap hanterar avslutande fel på omfångsnivå. När ett fel inträffar någonstans i omfånget trap för omslutning körs blocket.
-
Standard (nej
breakellercontinue): Felet visas och körningen fortsätter vid nästa instruktion efter den som orsakade felet. -
continuei trap: Undertrycker felmeddelandet och återupptas vid nästa instruktion. -
breaki trap: Felet sprids till det överordnade omfånget.
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'
Fullständig syntaxinformation finns i about_Trap.
Rapportera fel i funktioner och skript
När du skriver funktioner och skript väljer du den felrapporteringsmekanism som matchar felets allvarlighetsgrad.
Icke-avslutande – använd Write-Error
Använd Write-Error när funktionen kan fortsätta bearbeta andra indata. Detta är lämpligt för pipelinefunktioner som bearbetar flera objekt och stöter på fel på enskilda objekt.
function Test-Path-Safe {
[CmdletBinding()]
param([Parameter(ValueFromPipeline)][string]$Path)
process {
if (-not (Test-Path $Path)) {
Write-Error "Path not found: $Path"
return
}
$Path
}
}
Anmärkning
I avancerade funktioner (de med [CmdletBinding()]) använder du $PSCmdlet.WriteError() i stället för Write-Error att se till $false att det $? är korrekt inställt på i anroparens omfång. Cmdleten Write-Error är inte alltid korrekt inställd $? .
Instruktionsslutande – använd $PSCmdlet.ThrowTerminatingError()
Använd $PSCmdlet.ThrowTerminatingError() när funktionen inte kan fortsätta alls, men anroparen bör bestämma hur felet ska hanteras. Detta är den rekommenderade metoden i avancerade funktioner.
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
}
När felet lämnar funktionen behandlar anroparen det som ett icke-avslutande fel som standard. Anroparen kan eskalera den med -ErrorAction Stop.
Skriptslutning – använd throw
Använd throw när återställning inte är möjligt och hela skriptet ska stoppas.
$config = Get-Content 'config.json' -ErrorAction SilentlyContinue |
ConvertFrom-Json
if (-not $config) {
throw 'Cannot proceed without a valid configuration file.'
}
Vilken mekanism som ska användas
- När du bearbetar flera indata där vissa kan misslyckas använder du
Write-Erroreller$PSCmdlet.WriteError(). - Om funktionen inte kan fortsätta använder
$PSCmdlet.ThrowTerminatingError()du och låter anroparen bestämma hur den ska hanteras. - Om hela skriptet måste stoppas omedelbart använder du
throw.
Sammanfattning av feltyper
I följande tabeller sammanfattas egenskaperna och beteendet för de olika feltyperna i PowerShell.
Icke-avslutande fel
Icke-avslutande fel kan genereras av Write-Error eller $PSCmdlet.WriteError().
| Attribute | Beskrivning |
|---|---|
| Påverkans omfattning | Pipelinen fortsätter |
Fångad av catch |
Nej (om inte eskalerat) |
Fångad av trap |
Nej (om inte eskalerat) |
Har lagts till i $Error |
Ja (om inte Ignore) |
Anger $? till $false |
Ja |
Påverkas av -ErrorAction |
Ja |
Påverkas av $ErrorActionPreference |
Ja |
Instruktionsslutfel
Instruktionsslutfel kan genereras av ThrowTerminatingError(), motorfel, .NET-metodfel eller -ErrorAction Stop i avancerade kontexter.
| Attribute | Beskrivning |
|---|---|
| Påverkans omfattning | Aktuell instruktion stoppas; skriptet fortsätter |
Fångad av catch |
Ja |
Fångad av trap |
Ja |
Har lagts till i $Error |
Ja |
Anger $? till $false |
Ja |
Påverkas av -ErrorAction |
Nej (Break endast) |
Påverkas av $ErrorActionPreference |
Ja (kan undertrycka) |
Skriptslutfel
Skriptslutfel kan genereras av throw, parsa fel eller -ErrorAction Stop i icke-avancerade kontexter.
| Attribute | Beskrivning |
|---|---|
| Påverkans omfattning | Varva ned samtalsstacken |
Fångad av catch |
Ja |
Fångad av trap |
Ja |
Har lagts till i $Error |
Ja |
Anger $? till $false |
Ja |
Påverkas av -ErrorAction |
No |
Påverkas av $ErrorActionPreference |
throw: Ja (kan undertrycka) |
Påverkas av $ErrorActionPreference |
Eskalerad: beror på kontext |