Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Descrizione breve
Descrive i tipi di errori in PowerShell e i meccanismi per gestirli.
Descrizione lunga
PowerShell distingue tre categorie di errori:
- Errori non irreversibili
- Errori di terminazione delle istruzioni
- Errori di terminazione dello script
La comprensione della distinzione è essenziale per la scrittura di moduli e script affidabili, perché ogni categoria ha un comportamento predefinito diverso e richiede tecniche di gestione diverse.
Inoltre, i programmi esterni (nativi) segnalano errori tramite codici di uscita, che PowerShell tiene traccia separatamente dal proprio sistema di errore.
Tipi di errori
Errori non irreversibili
Un errore non irreversibile segnala un problema ma non arresta la pipeline. Il comando continua a elaborare gli oggetti di input successivi. Gli errori non irreversibili vengono generati da:
- Cmdlet
Write-Error - Metodo
$PSCmdlet.WriteError()nelle funzioni avanzate - Cmdlet che riscontrano errori ripristinabili nei singoli oggetti di input
Per impostazione predefinita, PowerShell visualizza il messaggio di errore e continua l'esecuzione.
# Non-terminating error: the pipeline continues after the failure
'file1.txt', 'noSuchFile.txt', 'file3.txt' | ForEach-Object {
Get-Content $_ -ErrorAction Continue
}
In questo esempio viene Get-Content segnalato un errore non irreversibile per noSuchFile.txt e quindi continua l'elaborazione file3.txtdi .
Gli errori non irreversibili non vengono attivati catch o trap per impostazione predefinita.
Errori di terminazione delle istruzioni
Un errore di terminazione dell'istruzione interrompe l'esecuzione dell'istruzione corrente (pipeline), ma l'esecuzione continua con l'istruzione successiva nello script. Gli errori di terminazione delle istruzioni vengono generati da:
- Metodo
$PSCmdlet.ThrowTerminatingError()nelle funzioni avanzate e nei cmdlet compilati - Errori del motore, ad
CommandNotFoundExceptionesempio (chiamata di un comando che non esiste) eParameterBindingException(argomenti di parametro non validi) - Chiamate al metodo .NET che generano eccezioni, ad esempio
[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'
Gli errori di terminazione delle istruzioni possono essere rilevati da try/catch e trap.
Annotazioni
.ThrowTerminatingError() non consulta il -ErrorAction parametro ( ad eccezione del Break valore , che immette il debugger). Tuttavia, $ErrorActionPreferencesi applica agli errori di terminazione delle istruzioni tramite il gestore a livello di istruzione del motore. Ad esempio, $ErrorActionPreference = 'SilentlyContinue' può eliminare un errore di terminazione dell'istruzione in modo che lo script continui all'istruzione successiva. Il -ErrorAction parametro non può eseguire questa operazione. Per informazioni dettagliate, vedere l'$ErrorActionPreference asimmetria.
Errori di terminazione dello script
Un errore di terminazione dello script rimuove l'intero stack di chiamate. L'esecuzione viene arrestata completamente a meno che l'errore non venga intercettato da un try/catch blocco o trap un'istruzione . Gli errori di terminazione dello script vengono generati da:
- Parola chiave
throw - Errori di analisi (errori di sintassi che impediscono la compilazione dello script)
- Errori non irreversibili inoltrati da
-ErrorAction Stopo$ErrorActionPreference = 'Stop'in contesti non avanzati. Per altre informazioni, vedere Funzionamento dell'escalation. - Alcuni errori critici del motore
# 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)'
La throw parola chiave genera un errore di terminazione dello script per impostazione predefinita. Tuttavia, $ErrorActionPreferencepuò eliminare throw se impostato su SilentlyContinue o Ignore. Quando si chiama una funzione avanzata con -ErrorAction SilentlyContinue, il parametro si traduce in un valore locale $ErrorActionPreference dell'ambito, quindi elimina throw anche all'interno di tale funzione.
Annotazioni
Anche con $ErrorActionPreference = 'Ignore', un throw oggetto eliminato registra ancora una voce in $Error. Il Ignore valore impedisce solo la registrazione per errori non irreversibili$Error.
Importante
I termini statement-terminating e script-terminating descrivono l'ambito di impatto, non la gravità dell'errore. Un errore di terminazione dell'istruzione arresta un'istruzione. Un errore di terminazione dello script arresta l'intero script e i relativi chiamanti. Entrambi possono essere intercettati da try/catch.
Errori del programma esterno
I programmi esterni (nativi) non partecipano direttamente al sistema di errori di PowerShell. Segnalano un errore tramite un codice di uscita diverso da zero, che PowerShell archivia nella $LASTEXITCODE variabile automatica.
git clone https://example.com/nonexistent.git 2>$null
if ($LASTEXITCODE -ne 0) {
Write-Error "git failed with exit code $LASTEXITCODE"
}
Per impostazione predefinita, un codice di uscita diverso da zero da un programma nativo:
- Imposta su
$?$false -
Non genera un in
ErrorRecord$Error -
Non attiva
catchotrap
PowerShell 7.3 ha aggiunto la variabile di preferenza sperimentale $PSNativeCommandUseErrorActionPreference, che è diventata una funzionalità stabile nella versione 7.4. Quando si imposta questa variabile su $true, genera un codice di uscita diverso da zero per generare un errore non irreversibile il cui messaggio indica il codice di uscita specifico (a NativeCommandExitException). Questo errore rispetta $ErrorActionPreference, quindi impostandolo per Stop promuovere l'errore a un errore di terminazione dello script che può essere intercettato con/trycatch .
Variabili di stato degli errori
PowerShell gestisce diverse variabili automatiche che riflettono lo stato di errore corrente.
$?
Contiene $true se l'ultima operazione ha avuto esito positivo e $false se ha generato un errore (senza terminazione o terminazione). Per i comandi nativi, $? è impostato in base al codice di uscita: $true per il codice 0di uscita , $false in caso contrario.
Get-Item -Path 'C:\NoSuchFile.txt' 2>$null
$? # False
$Error
Oggetto ArrayList che archivia i record di errore più recenti, con l'errore più recente in corrispondenza dell'indice 0. L'elenco contiene fino a $MaximumErrorCount voci (impostazione predefinita 256).
Tutti gli errori di terminazione vengono aggiunti a $Error. Per gli errori di terminazione, Ignore elimina la visualizzazione ma registra comunque l'errore in $Error. Tutti i non terminanti vengono aggiunti a $Error , a meno che non -ErrorAction Ignore vengano utilizzati in errori non irreversibili, che impediscono sia la visualizzazione che la registrazione.
$LASTEXITCODE
Contiene il codice di uscita dell'ultimo programma nativo eseguito. Un valore convenzionalmente 0 indica l'esito positivo. Qualsiasi valore diverso da zero indica un errore. Questa variabile non è interessata dagli errori del cmdlet di PowerShell.
Controllare il comportamento degli errori
Parametro -ErrorAction comune
Il parametro comune esegue l'override -ErrorAction$ErrorActionPreference di un singolo comando. Controlla in che modo PowerShell risponde a errori non irreversibili da tale comando.
| Valore | Comportamento |
|---|---|
Continue |
Visualizzare l'errore e continuare (impostazione predefinita) |
SilentlyContinue |
Eliminare la visualizzazione, aggiungere a $Error, continuare |
Ignore |
Elimina la visualizzazione e non aggiungi a $Error |
Stop |
Eseguire l'escalation a un errore irreversibile (vedere Funzionamento dell'escalation) |
Inquire |
Richiedere all'utente una decisione |
Break |
Immettere il debugger |
-ErrorAction non modifica il comportamento degli errori generati da $PSCmdlet.ThrowTerminatingError(). Tali errori vengono sempre terminati con istruzioni indipendentemente dalla preferenza del chiamante.
Variabile $ErrorActionPreference
La $ErrorActionPreference variabile di preferenza si applica a tutti i comandi nell'ambito corrente e negli ambiti figlio. Accetta gli stessi valori di -ErrorAction.
$ErrorActionPreference = 'Stop'
# All non-terminating errors in this scope now become terminating
Write-Error 'This now throws' # Generates ActionPreferenceStopException
Quando -ErrorAction viene specificato in un comando, ha la precedenza $ErrorActionPreference su tale comando.
Funzionamento dell'escalation
Quando -ErrorAction Stop o $ErrorActionPreference = 'Stop' è attivo, PowerShell converte gli errori non irreversibili in errori irreversibili usando il meccanismo seguente:
- Un cmdlet chiama
WriteError()internamente per generare un errore non irreversibile. - Il motore controlla la preferenza effettiva
ErrorActionper il comando. - Poiché la preferenza è
Stop, il motore crea un oggettoActionPreferenceStopExceptionche esegue il wrapping del record di errore originale. - Se rilevata da
catch, le informazioni di errore originali sono accessibili tramite$_.Exception.ErrorRecord.
L'ambito dell'errore inoltrato dipende dal contesto:
- In script, funzioni o blocchi di script non avanzati , l'impostazione
$ErrorActionPreference = 'Stop'esegue l'escalation a un errore di terminazione dello script . L'errore propaga lo stack di chiamate. - Nelle funzioni avanzate e nei blocchi di script (quelli con
[CmdletBinding()]), l'errore rimane in fase di terminazione. L'esecuzione continua all'istruzione successiva dopo la chiamata. - Il passaggio
-ErrorAction Stopa una funzione avanzata ha lo stesso effetto dell'impostazione$ErrorActionPreference = 'Stop'al suo interno, perché-ErrorActionsi traduce in un valore locale$ErrorActionPreferencedell'ambito.
Esempi di escalation
NON avanzato: terminazione dello script ('after' non stampa)
& { param() $ErrorActionPreference = 'Stop' Get-Item 'NoSuchPath' } 2>$null 'after'ADVANCED: terminazione dell'istruzione ('after' DOES print)
& { [CmdletBinding()] param() $ErrorActionPreference = 'Stop'; Get-Item 'NoSuchPath' } 2>$null 'after'Senza
-ErrorAction Stop: non terminazione, catch non viene eseguitotry { Write-Error 'This is non-terminating' Write-Output 'Execution continues' } catch { Write-Output "Caught: $_" # Not reached }Con
-ErrorAction Stop: è stato inoltrato alla terminazionetry { Write-Error 'This becomes terminating' -ErrorAction Stop } catch { Write-Output "Caught: $_" # Reached }
Gli errori inoltrati possono essere rilevati dal tipo di eccezione originale. Il motore annulla il wrapping di ActionPreferenceStopException per trovare l'eccezione sottostante:
try {
Get-Item -Path 'C:\NoSuchFile.txt' -ErrorAction Stop
} catch [System.Management.Automation.ItemNotFoundException] {
Write-Output "File not found: $($_.Exception.Message)"
}
Asymmetry $ErrorActionPreference
Il -ErrorAction parametro e la $ErrorActionPreference variabile si comportano in modo diverso con errori di terminazione. È importante comprendere questi dati asimmetria:
-ErrorActioninfluisce solo sugli errori non irreversibili . Quando un cmdlet chiama$PSCmdlet.ThrowTerminatingError(), il-ErrorActionparametro viene ignorato (ad eccezione diBreak, che immette il debugger). L'errore viene sempre generato.$ErrorActionPreferenceinfluisce sugli errori non irreversibili e di terminazione delle istruzioni. Il gestore degli errori a livello di istruzione del motore legge$ErrorActionPreference(non il-ErrorActionparametro) e può eliminare un errore di terminazione dell'istruzione quando il valore èSilentlyContinueoIgnore.
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'
Importante
$ErrorActionPreference non può eliminare gli errori SuppressPromptInInterpreter impostati su true. Questi vengono sempre propagati indipendentemente dalla variabile di preferenza. Alcuni esempi di questo tipo di errore includono:
-
ActionPreferenceStopExceptiondall'escalation-ErrorAction Stop - Errori all'interno dei metodi della classe PowerShell
PipelineStoppedException
Gestire gli errori
try/catch/finally
Usare try/catch/finally per gestire gli errori di terminazione delle istruzioni e di terminazione dello script. Quando si verifica un errore all'interno di un try blocco, PowerShell cerca un blocco corrispondente catch . Il finally blocco viene sempre eseguito, indipendentemente dal fatto che si sia verificato o meno un errore.
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
}
All'interno di un try blocco, il motore imposta un flag interno che causa l'escalation di errori non irreversibili da -ErrorAction Stop o $ErrorActionPreference = 'Stop' la propagazione al catch blocco. Questo comportamento è progettato, non un caso speciale.
Per informazioni dettagliate sulla sintassi, vedere about_Try_Catch_Finally.
trap
L'istruzione trap gestisce gli errori di terminazione a livello di ambito. Quando si verifica un errore in qualsiasi punto dell'ambito di inclusione, il trap blocco viene eseguito.
-
Valore predefinito (no
breakocontinue): l'errore viene visualizzato e l'esecuzione continua all'istruzione successiva dopo quella che ha causato l'errore. -
continuenella trap: elimina il messaggio di errore e riprende all'istruzione successiva. -
breaknella trap: l'errore si propaga all'ambito padre.
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'
Per informazioni dettagliate sulla sintassi, vedere about_Trap.
Segnalazione di errori in funzioni e script
Quando si scrivono funzioni e script, scegliere il meccanismo di segnalazione degli errori che corrisponde alla gravità dell'errore.
Non terminazione - uso Write-Error
Usare Write-Error quando la funzione può continuare a elaborare altri input. Questa opzione è appropriata per le funzioni della pipeline che elaborano più oggetti e riscontrano errori nei singoli elementi.
function Test-Path-Safe {
[CmdletBinding()]
param([Parameter(ValueFromPipeline)][string]$Path)
process {
if (-not (Test-Path $Path)) {
Write-Error "Path not found: $Path"
return
}
$Path
}
}
Annotazioni
Nelle funzioni avanzate (quelle con [CmdletBinding()]), usare $PSCmdlet.WriteError() invece di Write-Error per assicurarsi che $? sia impostato correttamente su $false nell'ambito del chiamante. Il Write-Error cmdlet non viene sempre impostato $? correttamente.
Statement-terminating - use $PSCmdlet.ThrowTerminatingError()
Usare $PSCmdlet.ThrowTerminatingError() quando la funzione non può continuare, ma il chiamante deve decidere come gestire l'errore. Questo è l'approccio consigliato nelle funzioni avanzate.
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
}
Dopo che l'errore lascia la funzione, il chiamante lo considera come un errore non irreversibile per impostazione predefinita. Il chiamante può inoltrarlo con -ErrorAction Stop.
Terminazione dello script- uso throw
Usare throw quando il ripristino non è possibile e l'intero script deve essere arrestato.
$config = Get-Content 'config.json' -ErrorAction SilentlyContinue |
ConvertFrom-Json
if (-not $config) {
throw 'Cannot proceed without a valid configuration file.'
}
Quale meccanismo usare
- Quando si elaborano più input in cui alcuni potrebbero non riuscire, usare
Write-Erroro$PSCmdlet.WriteError(). - Se la funzione non può continuare, usare
$PSCmdlet.ThrowTerminatingError()e consentire al chiamante di decidere come gestirla. - Se l'intero script deve essere arrestato immediatamente, usare
throw.
Riepilogo dei tipi di errore
Le tabelle seguenti riepilogano le proprietà e i comportamenti dei diversi tipi di errore in PowerShell.
Errore non irreversibile
Gli errori non irreversibili possono essere generati da Write-Error o $PSCmdlet.WriteError().
| Attribute | Descrizione |
|---|---|
| Ambito dell'impatto | La pipeline continua |
Catturato da catch |
No (a meno che non venga inoltrata) |
Catturato da trap |
No (a meno che non venga inoltrata) |
Aggiunta a $Error |
Sì (a meno che Ignore) |
Imposta su $?$false |
Sì |
Interessato da -ErrorAction |
Sì |
Interessato da $ErrorActionPreference |
Sì |
Errore di terminazione dell'istruzione
Gli errori di terminazione delle istruzioni possono essere generati da ThrowTerminatingError()errori del motore, eccezioni del metodo .NET o -ErrorAction Stop in contesti avanzati.
| Attribute | Descrizione |
|---|---|
| Ambito dell'impatto | L'istruzione corrente si arresta; script continua |
Catturato da catch |
Sì |
Catturato da trap |
Sì |
Aggiunta a $Error |
Sì |
Imposta su $?$false |
Sì |
Interessato da -ErrorAction |
No (Break solo) |
Interessato da $ErrorActionPreference |
Sì (può eliminare) |
Errore di terminazione dello script
Gli errori di terminazione dello script possono essere generati da throw, analizzare gli errori o -ErrorAction Stop in contesti non avanzati.
| Attribute | Descrizione |
|---|---|
| Ambito dell'impatto | Rimozione dello stack di chiamate |
Catturato da catch |
Sì |
Catturato da trap |
Sì |
Aggiunta a $Error |
Sì |
Imposta su $?$false |
Sì |
Interessato da -ErrorAction |
No |
Interessato da $ErrorActionPreference |
throw: Sì (può eliminare) |
Interessato da $ErrorActionPreference |
Escalation: dipende dal contesto |