Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Korte beschrijving
Beschrijft de typen fouten in PowerShell en de mechanismen voor het afhandelen ervan.
Lange beschrijving
PowerShell onderscheidt drie soorten fouten:
- Niet-afsluitfouten
- Fouten bij het beëindigen van instructies
- Fouten bij het beëindigen van scripts
Het begrijpen van het onderscheid is essentieel voor het schrijven van betrouwbare scripts en modules, omdat elke categorie verschillend standaardgedrag heeft en verschillende afhandelingstechnieken vereist.
Bovendien melden externe (systeemeigen) programma's een fout via afsluitcodes, die PowerShell afzonderlijk van zijn eigen foutsysteem bijhoudt.
Soorten fouten
Niet-afsluitfouten
Een niet-afsluitfout meldt een probleem, maar stopt de pijplijn niet. De opdracht gaat verder met het verwerken van volgende invoerobjecten. Niet-afsluitfouten worden gegenereerd door:
- De
Write-Errorcmdlet - De
$PSCmdlet.WriteError()methode in geavanceerde functies - Cmdlets die kunnen worden hersteld voor afzonderlijke invoerobjecten
Standaard wordt in PowerShell het foutbericht weergegeven en wordt de uitvoering voortgezet.
# Non-terminating error: the pipeline continues after the failure
'file1.txt', 'noSuchFile.txt', 'file3.txt' | ForEach-Object {
Get-Content $_ -ErrorAction Continue
}
In dit voorbeeld Get-Content wordt een niet-afsluitfout gerapporteerd voor noSuchFile.txt en wordt vervolgens de verwerking file3.txtvoortgezet.
Niet-afsluitfouten worden niet geactiveerd catch of trap standaard.
Fouten bij het beëindigen van instructies
Een instructie-afsluitfout voorkomt dat de huidige instructie (pijplijn) wordt uitgevoerd, maar de uitvoering wordt voortgezet bij de volgende instructie in het script. Fouten bij het beëindigen van instructies worden gegenereerd door:
- De
$PSCmdlet.ThrowTerminatingError()methode in geavanceerde functies en gecompileerde cmdlets - Enginefouten zoals
CommandNotFoundException(aanroepen van een opdracht die niet bestaat) enParameterBindingException(ongeldige parameterargumenten) - .NET-methode roept uitzonderingen op, zoals
[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'
Fouten bij het beëindigen van instructies kunnen worden ondervangen door try/catch en trap.
Opmerking
.ThrowTerminatingError() raadpleegt -ErrorAction de parameter niet (met uitzondering van de Break waarde die het foutopsporingsprogramma invoert).
$ErrorActionPreference
Is echter van toepassing op instructie-afsluitfouten via de handler op instructieniveau van de engine. Kan bijvoorbeeld $ErrorActionPreference = 'SilentlyContinue' een instructie-afsluitfout onderdrukken, zodat het script bij de volgende instructie wordt voortgezet. De -ErrorAction parameter kan dit niet doen. Zie de $ErrorActionPreference asymmetrie voor meer informatie.
Fouten bij het beëindigen van scripts
Een script-afsluitfout verwikkelt de volledige aanroepstack. Uitvoering stopt volledig tenzij de fout wordt opgevangen door een try/catch blok of trap instructie. Scripteindfouten worden gegenereerd door:
- Het
throw-trefwoord - Fouten parseren (syntaxisfouten die verhinderen dat het script wordt gecompileerd)
- Niet-afsluitfouten geëscaleerd door
-ErrorAction Stopof$ErrorActionPreference = 'Stop'in niet-geavanceerde contexten. Zie Hoe escalatie werkt voor meer informatie. - Bepaalde kritieke enginefouten
# 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)'
Met throw het trefwoord wordt standaard een scripteindfout gegenereerd.
$ErrorActionPreference
Kan echter onderdrukken throw wanneer deze is ingesteld op SilentlyContinue of Ignore. Wanneer u een geavanceerde functie aanroept, -ErrorAction SilentlyContinuewordt de parameter omgezet in een bereik-lokale $ErrorActionPreference waarde, zodat deze ook in die functie wordt onderdrukt throw .
Opmerking
Zelfs met $ErrorActionPreference = 'Ignore', een throw die wordt onderdrukt, registreert nog steeds een vermelding in $Error. De Ignore waarde voorkomt alleen het $Error opnemen van niet-afsluitfouten .
Belangrijk
In de termen voor het beëindigen van de instructie en scripteinding wordt het bereik van de impact beschreven, niet de ernst van de fout. Een instructie-afsluitfout stopt één instructie. Een script-afsluitfout stopt het hele script en de aanroepers. Beide kunnen worden gevangen door try/catch.
Fouten in externe programma's
Externe (systeemeigen) programma's nemen niet rechtstreeks deel aan het foutsysteem van PowerShell. Ze melden fouten via een afsluitcode die niet nul is, die in PowerShell wordt opgeslagen in de $LASTEXITCODE automatische variabele.
git clone https://example.com/nonexistent.git 2>$null
if ($LASTEXITCODE -ne 0) {
Write-Error "git failed with exit code $LASTEXITCODE"
}
Standaard is een niet-nul afsluitcode van een systeemeigen programma:
- Hiermee wordt ingesteld
$?op$false - Genereert geen
ErrorRecordin$Error - Wordt niet geactiveerd
catchoftrap
PowerShell 7.3 heeft de experimentele voorkeursvariabele $PSNativeCommandUseErrorActionPreferencetoegevoegd, die een stabiele functie werd in 7.4. Wanneer u deze variabele $trueinstelt op, wordt er een afsluitcode die niet nul is, een niet-afsluitfout verzonden waarvan het bericht de specifieke afsluitcode (a NativeCommandExitException) aangeeft. Deze fout respecteert$ErrorActionPreference, dus het instellen ervan om de fout te Stop bevorderen op een script-afsluitfout die kan worden opgevangen met/trycatch .
Foutstatusvariabelen
PowerShell onderhoudt verschillende automatische variabelen die de huidige foutstatus weerspiegelen.
$?
Bevat $true of de laatste bewerking is geslaagd en $false of er een fout is opgetreden (niet-afsluiten of beëindigen). Voor systeemeigen opdrachten $? wordt ingesteld op basis van de afsluitcode: $true voor afsluitcode 0, $false anders.
Get-Item -Path 'C:\NoSuchFile.txt' 2>$null
$? # False
$Error
Een ArrayList record waarin de meest recente foutrecords worden opgeslagen, met de meest recente fout bij de index 0. De lijst bevat maximaal $MaximumErrorCount vermeldingen (standaard 256).
Alle afsluitfouten worden toegevoegd aan $Error. Voor afsluitfouten Ignore onderdrukt u de weergave, maar registreert u de fout nog steeds in $Error. Alle niet-afsluitfouten worden toegevoegd aan $Error tenzij -ErrorAction Ignore ze worden gebruikt bij niet-afsluitfouten, waardoor zowel weergave als opname worden voorkomen.
$LASTEXITCODE
Bevat de afsluitcode van het laatste systeemeigen programma dat is uitgevoerd. Een waarde van 0 conventioneel duidt op succes. Elke waarde die niet nul is, geeft aan dat de fout is mislukt. Deze variabele wordt niet beïnvloed door PowerShell-cmdlet-fouten.
Gedrag van besturingsfouten
De -ErrorAction algemene parameter
De -ErrorAction algemene parameter overschrijft $ErrorActionPreference voor één opdracht. Het bepaalt hoe PowerShell reageert op niet-afsluitfouten van die opdracht.
| Waarde | Gedrag |
|---|---|
Continue |
De fout weergeven en doorgaan (standaard) |
SilentlyContinue |
Weergave onderdrukken, toevoegen aan $Error, doorgaan |
Ignore |
Weergave onderdrukken en niet toevoegen aan $Error |
Stop |
Escaleren naar een afsluitfout (zie Hoe escalatie werkt) |
Inquire |
De gebruiker vragen om een beslissing |
Break |
Voer het foutopsporingsprogramma in |
-ErrorAction wijzigt het gedrag van fouten die worden gegenereerd door $PSCmdlet.ThrowTerminatingError(). Deze fouten zijn altijd instructie-afsluit, ongeacht de voorkeur van de beller.
De $ErrorActionPreference variabele
De $ErrorActionPreference voorkeursvariabele is van toepassing op alle opdrachten in het huidige bereik en onderliggende bereiken. Deze accepteert dezelfde waarden als -ErrorAction.
$ErrorActionPreference = 'Stop'
# All non-terminating errors in this scope now become terminating
Write-Error 'This now throws' # Generates ActionPreferenceStopException
Wanneer -ErrorAction wordt opgegeven voor een opdracht, heeft deze voorrang op $ErrorActionPreference die opdracht.
Hoe escalatie werkt
Wanneer -ErrorAction Stop of $ErrorActionPreference = 'Stop' in werking is, converteert PowerShell niet-afsluitfouten naar afsluitfouten met behulp van het volgende mechanisme:
- Een cmdlet roept
WriteError()intern aan om een niet-afsluitfout te verzenden. - De engine controleert de effectieve
ErrorActionvoorkeur voor de opdracht. - Omdat de voorkeur is
Stop, maakt de engine eenActionPreferenceStopExceptiondie de oorspronkelijke foutrecord verpakt. - Als dit wordt onderschept
catch, is de oorspronkelijke foutinformatie toegankelijk via$_.Exception.ErrorRecord.
Het bereik van de geëscaleerde fout is afhankelijk van de context:
- Bij niet-geavanceerde scripts, functies of scriptblokken escaleert het instellen
$ErrorActionPreference = 'Stop'van escalatie naar een fout bij het beëindigen van scripts. De fout wordt doorgegeven aan de aanroepstack. - In geavanceerde functies en scriptblokken (met)
[CmdletBinding()]blijft de fout instructie-afsluiter. Uitvoering wordt voortgezet bij de volgende instructie na de aanroep. - Het doorgeven
-ErrorAction Stopaan een geavanceerde functie heeft hetzelfde effect als de instelling$ErrorActionPreference = 'Stop'erin, omdat-ErrorActiondeze wordt omgezet in een bereik-lokale$ErrorActionPreferencewaarde.
Voorbeelden van escalatie
NIET-geavanceerd: scripteinden ('after' wordt NIET afgedrukt)
& { param() $ErrorActionPreference = 'Stop' Get-Item 'NoSuchPath' } 2>$null 'after'GEAVANCEERD: statement-terminating ('after' DOES print)
& { [CmdletBinding()] param() $ErrorActionPreference = 'Stop'; Get-Item 'NoSuchPath' } 2>$null 'after'Zonder
-ErrorAction Stop: niet-afsluiten, wordt catch niet uitgevoerdtry { Write-Error 'This is non-terminating' Write-Output 'Execution continues' } catch { Write-Output "Caught: $_" # Not reached }Met
-ErrorAction Stop: geëscaleerd naar beëindigingtry { Write-Error 'This becomes terminating' -ErrorAction Stop } catch { Write-Output "Caught: $_" # Reached }
Geëscaleerde fouten kunnen worden opgevangen door het oorspronkelijke uitzonderingstype. De engine pakt de ActionPreferenceStopException onderliggende uitzondering uit:
try {
Get-Item -Path 'C:\NoSuchFile.txt' -ErrorAction Stop
} catch [System.Management.Automation.ItemNotFoundException] {
Write-Output "File not found: $($_.Exception.Message)"
}
De $ErrorActionPreference asymmetrie
De -ErrorAction parameter en de $ErrorActionPreference variabele gedragen zich anders met afsluitfouten. Het is belangrijk om deze asymmetrie te begrijpen:
-ErrorActionis alleen van invloed op niet-afsluitfouten . Wanneer een cmdlet wordt aangeroepen$PSCmdlet.ThrowTerminatingError(), wordt de-ErrorActionparameter genegeerd (met uitzondering vanBreak, waarmee het foutopsporingsprogramma wordt ingevoerd). De fout wordt altijd gegenereerd.$ErrorActionPreferenceis van invloed op zowel niet-afsluit- als instructie-afsluitfouten. De fouthandler op instructieniveau van de engine leest$ErrorActionPreference(niet de-ErrorActionparameter) en kan een instructiebeëindigingsfout onderdrukken wanneer de waarde ofSilentlyContinueIgnore.
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'
Belangrijk
$ErrorActionPreference kan fouten die zijn SuppressPromptInInterpreter ingesteld trueop . Deze worden altijd doorgegeven, ongeacht de voorkeursvariabele. Voorbeelden van dit type fout zijn:
-
ActionPreferenceStopExceptionvan-ErrorAction Stopescalatie - Fouten in PowerShell-klassemethoden
PipelineStoppedException
Afhandeling van fouten
try/catch/finally
Gebruik try/catch/finally dit voor het afhandelen van fouten bij het beëindigen van instructies en het beëindigen van scripts. Wanneer er een fout optreedt in een try blok, zoekt PowerShell naar een overeenkomend catch blok. Het finally blok wordt altijd uitgevoerd, ongeacht of er een fout is opgetreden.
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
}
Binnen een try blok stelt de engine een interne vlag in die niet-afsluitfouten veroorzaakt die zijn geëscaleerd door -ErrorAction Stop of $ErrorActionPreference = 'Stop' om door te geven aan het catch blok. Dit is ontworpen gedrag, geen speciaal geval.
Zie about_Try_Catch_Finally voor volledige syntaxisdetails.
trap
De trap instructie verwerkt afsluitfouten op bereikniveau. Wanneer er een fout optreedt ergens in het bereik insluiten, wordt het trap blok uitgevoerd.
-
Standaard (nee
breakofcontinue): de fout wordt weergegeven en de uitvoering wordt voortgezet op de volgende instructie na de instructie die de fout heeft veroorzaakt. -
continuein de trap: onderdrukt het foutbericht en hervat bij de volgende instructie. -
breakin de trap: de fout wordt doorgegeven aan het bovenliggende bereik.
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'
Zie about_Trap voor volledige syntaxisdetails.
Fouten rapporteren in functies en scripts
Kies bij het schrijven van functies en scripts het mechanisme voor foutrapportage dat overeenkomt met de ernst van de fout.
Niet-afsluiten - gebruik Write-Error
Gebruik Write-Error deze functie wanneer de functie andere invoer kan blijven verwerken. Dit is geschikt voor pijplijnfuncties die meerdere objecten verwerken en fouten ondervinden voor afzonderlijke items.
function Test-Path-Safe {
[CmdletBinding()]
param([Parameter(ValueFromPipeline)][string]$Path)
process {
if (-not (Test-Path $Path)) {
Write-Error "Path not found: $Path"
return
}
$Path
}
}
Opmerking
Gebruik in geavanceerde functies (die met [CmdletBinding()]), $PSCmdlet.WriteError() in plaats van Write-Error ervoor te zorgen dat deze $? juist is ingesteld $false in het bereik van de aanroeper. De Write-Error cmdlet is niet altijd correct ingesteld $? .
Instructie-afsluit - gebruik $PSCmdlet.ThrowTerminatingError()
Gebruik $PSCmdlet.ThrowTerminatingError() deze functie als de functie helemaal niet kan doorgaan, maar de aanroeper moet beslissen hoe de fout moet worden afgehandeld. Dit is de aanbevolen benadering in geavanceerde functies.
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
}
Nadat de fout de functie verlaat, behandelt de aanroeper deze standaard als een niet-afsluitfout. De beller kan het escaleren met -ErrorAction Stop.
Scriptafeinding - gebruik throw
Gebruik throw dit wanneer herstel niet mogelijk is en het hele script moet stoppen.
$config = Get-Content 'config.json' -ErrorAction SilentlyContinue |
ConvertFrom-Json
if (-not $config) {
throw 'Cannot proceed without a valid configuration file.'
}
Welk mechanisme moet worden gebruikt
- Wanneer u meerdere invoergegevens verwerkt waarbij sommige mogelijk mislukken, gebruikt
Write-Errorof$PSCmdlet.WriteError(). - Als de functie niet kan doorgaan, gebruikt
$PSCmdlet.ThrowTerminatingError()u deze en laat u de aanroeper beslissen hoe deze moet worden afgehandeld. - Als het hele script onmiddellijk moet stoppen, gebruikt u
throw.
Samenvatting van fouttypen
De volgende tabellen bevatten een overzicht van de eigenschappen en het gedrag van de verschillende fouttypen in PowerShell.
Fout bij niet-beëindigen
Niet-afsluitfouten kunnen worden gegenereerd door Write-Error of $PSCmdlet.WriteError().
| Attribute | Beschrijving |
|---|---|
| Bereik van impact | Pijplijn wordt voortgezet |
Gevangen door catch |
Nee (tenzij geëscaleerd) |
Gevangen door trap |
Nee (tenzij geëscaleerd) |
Toegevoegd aan $Error |
Ja (tenzij Ignore) |
Hiermee wordt ingesteld $? op $false |
Ja |
Beïnvloed door -ErrorAction |
Ja |
Beïnvloed door $ErrorActionPreference |
Ja |
Instructie-afsluitfout
Fouten bij het beëindigen van instructies kunnen worden gegenereerd door ThrowTerminatingError(), enginefouten, .NET-methodeuitzonderingen of -ErrorAction Stop in geavanceerde contexten.
| Attribute | Beschrijving |
|---|---|
| Bereik van impact | Huidige instructie stopt; script wordt voortgezet |
Gevangen door catch |
Ja |
Gevangen door trap |
Ja |
Toegevoegd aan $Error |
Ja |
Hiermee wordt ingesteld $? op $false |
Ja |
Beïnvloed door -ErrorAction |
Nee (Break alleen) |
Beïnvloed door $ErrorActionPreference |
Ja (kan onderdrukken) |
Fout bij afsluiten van script
Scripteindfouten kunnen worden gegenereerd door throw, fouten parseren of -ErrorAction Stop in niet-geavanceerde contexten.
| Attribute | Beschrijving |
|---|---|
| Bereik van impact | Oproepstack komt tot rust |
Gevangen door catch |
Ja |
Gevangen door trap |
Ja |
Toegevoegd aan $Error |
Ja |
Hiermee wordt ingesteld $? op $false |
Ja |
Beïnvloed door -ErrorAction |
No |
Beïnvloed door $ErrorActionPreference |
throw: Ja (kan onderdrukken) |
Beïnvloed door $ErrorActionPreference |
Geëscaleerd: afhankelijk van context |