Powershell: come posso impedire la visualizzazione di errori in uno script?


92

Quando il mio script PowerShell tenta, ad esempio, di creare un oggetto SQL Server per un server che non esiste ("bla" nel mio caso), PowerShell visualizza molti errori di PowerShell in rosso.

Poiché il mio script controlla il valore di $?dopo tali chiamate e visualizza e registra gli errori, preferirei non visualizzare anche le diverse righe di errori di PowerShell.

Come posso disattivare quelli visualizzati per il mio script?

Risposte:


132

Hai un paio di opzioni. Il modo più semplice consiste nell'usare le ErrorActionimpostazioni.

-Erroractionè un parametro universale per tutti i cmdlet. Se ci sono comandi speciali che vuoi ignorare, puoi usarli, -erroraction 'silentlycontinue'che in pratica ignoreranno tutti i messaggi di errore generati da quel comando. Puoi anche usare il Ignorevalore (in PowerShell 3+):

A differenza di SilentlyContinue, Ignore non aggiunge il messaggio di errore alla variabile automatica $ Error.

Se vuoi ignorare tutti gli errori in uno script, puoi usare la variabile di sistema $ErrorActionPreferencee fare la stessa cosa:$ErrorActionPreference= 'silentlycontinue'

Vedere about_CommonParameters per ulteriori informazioni su -ErrorAction. Vedi about_preference_variables per maggiori informazioni su $ ErrorActionPreference.


hai bisogno di virgolette singole in -erroraction 'silenzientlycontinue'? Intellisese mostra le opzioni e non aggiunge virgolette singole.
PAS

1
Se il formato sopra non funziona per te, fai riferimento al link fornito sopra. Ho dovuto formattare come -ErrorAction:SilentlyContinuein PS 5.1. Stavo chiamando il mio cmdlet da batch quindi non so se questo fa la differenza. Ma buone informazioni quando sai che un errore accettabile potrebbe essere generato.
David

--rm. \ Windows.old \ -Force -Recurse -Verbose -ErrorAction SilentlyContinue -WarningAction SilentlyContinue </code>
Tertius Geldenhuys

18

Windows PowerShell fornisce due meccanismi per la segnalazione degli errori: un meccanismo per terminare gli errori e un altro meccanismo per gli errori non risolutivi .

Il codice CmdLets interno può chiamare un ThrowTerminatingErrormetodo quando si verifica un errore che non consente o non deve consentire al cmdlet di continuare a elaborare i propri oggetti di input. L'autore dello script può utilizzare l'eccezione per rilevare questi errori.

EX:

try
{
  Your database code
}
catch
{
  Error reporting/logging
}

Il codice CmdLets interno può chiamare un WriteErrormetodo per segnalare errori irreversibili quando il cmdlet può continuare a elaborare gli oggetti di input. Lo script writer può quindi utilizzare l'opzione -ErrorAction per nascondere i messaggi o utilizzare $ErrorActionPreferenceper impostare l'intero comportamento dello script.


8

Ho avuto un problema simile durante il tentativo di risolvere i nomi host utilizzando [system.net.dns]. Se l'IP non è stato risolto .Net ha generato un errore di terminazione. Per evitare l'errore di terminazione e mantenere comunque il controllo dell'output, ho creato una funzione utilizzando TRAP.

PER ESEMPIO

Function Get-IP 
{PARAM   ([string]$HostName="")
PROCESS {TRAP 
             {"" ;continue} 
             [system.net.dns]::gethostaddresses($HostName)
        }
}

3

Sei fuori strada qui.

Hai già un bel messaggio di errore grande. Perché mai vorresti scrivere codice che controlli $?esplicitamente dopo ogni singolo comando ? Questo è enormemente macchinoso e soggetto a errori. La soluzione corretta è interrompere il controllo$? .

Usa invece il meccanismo integrato di PowerShell per far saltare in aria per te. Lo abiliti impostando la preferenza di errore al livello più alto:

$ErrorActionPreference = 'Stop'

L'ho messo in cima a ogni singola sceneggiatura che ho scritto e ora non devo controllare $?. Questo rende il mio codice molto più semplice e affidabile.

Se ti imbatti in situazioni in cui hai davvero bisogno di disabilitare questo comportamento, puoi o catchl'errore o passare un'impostazione a una particolare funzione usando il common -ErrorAction. Nel tuo caso, probabilmente vuoi che il tuo processo si fermi al primo errore, lo rilevi e poi lo registri.

Si noti che questo non gestisce il caso in cui gli eseguibili esterni falliscono (codice di uscita diverso da zero, convenzionalmente), quindi è comunque necessario controllare $LASTEXITCODEse si invoca uno qualsiasi. Nonostante questa limitazione, l'impostazione consente di risparmiare molto codice e fatica.

Affidabilità aggiuntiva

Potresti anche prendere in considerazione l'utilizzo della modalità rigorosa :

Set-StrictMode -Version Latest

Ciò impedisce a PowerShell di procedere silenziosamente quando si utilizza una variabile inesistente e in altre situazioni strane. (Vedere il -Versionparametro per i dettagli su ciò che limita.)

La combinazione di queste due impostazioni rende PowerShell molto più di un linguaggio veloce, il che rende la programmazione molto più semplice.


2

Aggiungi -ErrorAction SilentlyContinuealla tua sceneggiatura e sarai a posto.


2

In alcuni casi è possibile reindirizzare dopo il comando un Out-Null

command | Out-Null

-1

Se desideri che il messaggio di errore di PowerShell per un cmdlet venga soppresso, ma desideri comunque rilevare l'errore, utilizza "-erroraction 'silentlyStop'"


Non esiste tale azione. Anche se c'è un'azione Stop.
Marvin Dickhaus

Ma consente di sopprimere il messaggio di errore rosso e continuare a utilizzare il comando / sezione catch quando si utilizza New-Item -ItemType directory(PowerShell v2.0)
Milan Kerslager

@MilanKerslager potresti gentilmente mostrare un esempio di codice - dato che io e tutti gli altri crediamo che non esista un ActionPreference come 'SilentlyStop'
FSCKur

Sono ragionevolmente fiducioso che Mikkel intendesse SilentlyContinue piuttosto che silentlyStop, perché questo ha molto più senso nel contenuto di ciò che vuoi che faccia.
John
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.