Una delle parti fondamentali di ogni buon script PowerShell è la gestione degli errori. Anche nello script più breve, essere in grado di gestire gli errori aiuta a garantire che un evento imprevisto non vada a distruggere il sistema su cui si sta lavorando. Prendi l’esempio qui sotto. Ogni settimana nella nostra azienda campione (MyCompany.Com) Le risorse umane stanno per caricare una lista che ci dice chi dovrebbe avere accesso al database delle spese., Se un nome non è nell’elenco da HR, lo rimuoveremo dal gruppo e quell’utente non sarà più in grado di registrare le richieste di spesa:
Ora, puoi vedere dove andrà storto. Una settimana HR non andare in giro per caricare la lista o, proprio come stiamo per accedere alla lista, il file server muore. Improvvisamente PowerShell genera un errore sul cmdlet Get-Content e la variabile Author AuthorizedUser rimane vuota. Poiché il nostro script non gestisce gli errori, continua a funzionare e, in un brevissimo lasso di tempo, ha rimosso ogni utente dal nostro gruppo spese., Molto presto le telefonate irate iniziano a inondare e la vita diventa un po ‘ meno felice. Il modo per evitare tutto questo è catturare gli errori e quindi gestire l’evento che li ha causati (che in questo caso è fermare lo script e gridare a qualcuno in HR).
Errori di terminazione e non terminazione
Una delle cose fondamentali da sapere quando si rilevano errori è che solo alcuni errori possono essere rilevati per impostazione predefinita. Gli errori sono di due tipi: terminanti e non terminanti. Un errore di terminazione è un errore che interrompe una funzione o un’operazione., Se si commette un errore di sintassi o si esaurisce la memoria, si tratta di un errore di terminazione. Gli errori di terminazione possono essere rilevati e gestiti. Gli errori non terminanti consentono a Powershell di continuare e di solito provengono da cmdlet o da altre situazioni gestite. In circostanze normali non possono essere catturati da Try-Catch-Finally. L’errore Get-Content nell’esempio precedente è un errore di non terminazione.
Trattare gli errori non terminanti come terminazione
Quindi come si rileva un errore non terminante? Fondamentalmente, dici a PowerShell di trattarlo come terminante. Per fare ciò si utilizza il parametro ErrorAction., Ogni cmdlet PowerShell supporta ErrorAction. Specificando-ErrorAction Stop alla fine di un cmdlet, assicurati che tutti gli errori che genera siano trattati come terminanti e possano essere rilevati. Nel nostro esempio sopra cambieremo la nostra riga Get-Content in:
$AuthorizedUsers= Get-Content \\ FileServer\HRShare\UserList.txt -ErrorAction Stop
Trattando tutti gli errori come Terminazione
È anche possibile trattare tutti gli errori come terminazione usando la variabile ErrorActionPreference. Puoi farlo per lo script con cui stai lavorando o per l’intera sessione di PowerShell. Per impostarlo in uno script, crea la prima riga Er ErrorActionPreference = Stop., Per impostarlo per la sessione, digitare Er ErrorActionPreference = Stop nella console PowerShell.
Cattura di un errore di terminazione
Una volta assicurato che l’errore che si sta tentando di catturare verrà trattato come terminante, è possibile creare un blocco Try Catch attorno al comando (o comandi) che potrebbe causare l’errore. Il primo stadio consiste nel circondare la sezione del tuo script che potrebbe generare l’errore con un blocco Try. Nel nostro esempio la riga Get-Content diventa:
Try{ $AuthorizedUsers= Get-Content \\ FileServer\HRShare\UserList.txt -ErrorAction Stop}
Subito dopo il blocco Try è necessario inserire un blocco Catch per gestire l’errore., Il blocco Catch è accessibile solo se si verifica un errore di terminazione, altrimenti viene ignorato. Nel nostro esempio ci accingiamo a inviare un’e-mail a un amministratore per dire che c’è stato un errore e quindi interrompere lo script. La nostra linea Get-Content è ora:
Accesso al record di errore
Una volta all’interno di un blocco catch è possibile accedere al record di errore, che è memorizzato nella variabile oggetto corrente, $_. I record di errore hanno varie proprietà utili, ma la principale a cui si desidera accedere è $_.Eccezione., Le eccezioni sono ciò con cui abbiamo veramente a che fare qui mentre catturiamo e gestiamo gli errori – le eccezioni sono l’evento imprevisto che ha causato l’errore (il record di errore stesso è in realtà solo un wrapper per presentare l’eccezione all’utente PowerShell). È l’eccezione che stiamo catturando e l’eccezione che contiene tutte le informazioni davvero utili sul problema. Se c’è stato un ulteriore problema di fondo che ha causato la nostra eccezione, viene anche registrato in $_.eccezione.innerexception (e così via – la prossima eccezione sottostante è memorizzata in $_.eccezione.eccezione interna.,innerexception ecc.). Ai fini del nostro esempio useremo $_.Eccezione per inserire alcune informazioni extra nella nostra e-mail di notifica, utilizzando il $_.Eccezione.Messaggio e__.Eccezione.Proprietà ItemName:
Cattura di eccezioni specifiche
Ora, come il nostro esempio, stiamo rilevando eventuali errori che si verificano durante il file letto e gestendoli tutti allo stesso modo. È tuttavia possibile rilevare eccezioni specifiche e gestirle in modo diverso, ma – ed è un grande ma – solo se l’errore originale si sta terminando., Poiché il cmdlet Get-Content genera errori non terminanti (che abbiamo trattato solo come terminanti usando ErrorAction) non possiamo catturare in modo specifico le diverse eccezioni che il cmdlet potrebbe generare. Questa è una funzionalità di PowerShell e si applica a qualsiasi errore non terminante, indipendentemente da ErrorActionPreference e non può essere modificato. Tuttavia, possiamo gestire altre eccezioni di terminazione, come un errore di memoria insufficiente, che potrebbe emergere durante l’operazione di lettura. Ai fini di questo esempio che è quello che faremo.,
Si rilevano errori di terminazione specifici specificando il nome dell’eccezione immediatamente dopo la parola chiave Catch. Nel nostro esempio vogliamo prendere un sistema.Eccezione OutOfMemory e, se ne otteniamo uno, prenderà l’approccio no nonsense di riavviare immediatamente il computer. Includeremo anche un blocco catch generale dopo il nostro blocco file not found per catturare tutte le altre eccezioni:
Infine, Usando Finally
L’ultima parte di Try Catch Finally è il blocco Finally. Questo deve essere definito immediatamente dopo il blocco Catch e viene eseguito ogni volta, indipendentemente dal fatto che si sia verificato un errore o meno., In questo modo è possibile eseguire azioni che devono essere eseguite indipendentemente dal fatto che un’operazione abbia esito positivo o negativo. Nel nostro esempio registreremo che è stato tentato di leggere un file. La nostra linea Get-Content ora assomiglia a: