{"id":276233,"date":"2024-06-18T08:41:52","date_gmt":"2024-06-18T08:41:52","guid":{"rendered":"https:\/\/www.ninjaone.com\/?p=276233"},"modified":"2025-05-16T08:46:47","modified_gmt":"2025-05-16T08:46:47","slug":"guida-alla-gestione-degli-errori-powershell","status":"publish","type":"post","link":"https:\/\/www.ninjaone.com\/it\/blog\/guida-alla-gestione-degli-errori-powershell\/","title":{"rendered":"Guida completa alla gestione degli errori PowerShell"},"content":{"rendered":"<p>PowerShell \u00e8 il principale linguaggio di scripting e riga di comando utilizzato dai sistemi operativi Windows. Consente di eseguire programmi e attivit\u00e0 di gestione del sistema da terminale ed \u00e8 ampiamente utilizzato da amministratori di sistema e sviluppatori per automatizzare i loro flussi di lavoro.<\/p>\n<p>La gestione degli errori \u00e8 una parte importante di qualsiasi sistema di <a href=\"https:\/\/www.ninjaone.com\/blog\/how-to-automate-tasks-with-powershell\/\" target=\"_blank\" rel=\"noopener\">scripting e automazione<\/a>. Se qualcosa va storto, i tuoi script PowerShell non dovrebbero semplicemente bloccarsi: dovrebbero identificare che si \u00e8 verificato un errore e intervenire per eseguire nuovamente l&#8217;operazione o per avvisarti che qualcosa \u00e8 andato storto in modo che tu possa trovare la causa e risolvere il problema.<\/p>\n<p>Questa guida si propone di fornirti una comprensione dettagliata della <strong>gestione degli errori Powershell<\/strong>, compresi i tipi di errori, le tecniche di gestione degli errori, gli esempi di come implementare la gestione degli errori nei tuoi script e le best practice per lanciare, catturare, registrare e rispondere agli errori.<\/p>\n<h2>Capire i tipi di errore in PowerShell<\/h2>\n<p>Esistono due tipi di errore che devi gestire in modo diverso per garantire l&#8217;affidabilit\u00e0 dei tuoi script PowerShell.<\/p>\n<p>I <a href=\"https:\/\/learn.microsoft.com\/en-us\/powershell\/scripting\/developer\/cmdlet\/terminating-errors?view=powershell-7.4\" target=\"_blank\" rel=\"noopener\">terminating error<\/a> (errori di terminazione) interrompono l&#8217;esecuzione del comando o dello script quando si verificano. Di solito si tratta di <a href=\"https:\/\/learn.microsoft.com\/en-us\/powershell\/scripting\/learn\/deep-dives\/everything-about-exceptions?view=powershell-7.4\" target=\"_blank\" rel=\"noopener\">eccezioni<\/a>, che possono essere gestite con i blocchi try\/catch (spiegati pi\u00f9 avanti in questo articolo). Le cause dei terminating error includono errori di sintassi (quando sbagli a digitare un comando o fornisci parametri non validi) ed errori interni all&#8217;applicazione o al comando in esecuzione.<\/p>\n<p>I <a href=\"https:\/\/learn.microsoft.com\/en-us\/powershell\/scripting\/developer\/cmdlet\/non-terminating-errors?view=powershell-7.4\" target=\"_blank\" rel=\"noopener\">non-terminating error<\/a> (errori non di terminazione) non interrompono l&#8217;esecuzione del comando o dello script: lo script PowerShell continuer\u00e0 a essere eseguito dopo il verificarsi dell&#8217;errore. Di solito, i non-terminating error mostrano un messaggio di errore prima che l&#8217;esecuzione riprenda e devono essere gestiti in modo diverso dai terminating error, in modo che non causino il malfunzionamento degli script se il loro output previsto viene richiesto in seguito. Gli errori non-terminating possono essere causati da timeout di rete, file mancanti o problemi di autorizzazioni che, pur non rappresentando un&#8217;eccezione o un errore critico nell&#8217;esecuzione in s\u00e9, se non vengono gestiti, possono causare un comportamento indesiderato.<\/p>\n<h2>Concetti di base sulla gestione degli errori PowerShell (try, catch, finally e $ErrorActionPreference)<\/h2>\n<p>Gli errori PowerShell di tipo terminating e le eccezioni vengono <em>lanciati<\/em> (si verifica l&#8217;errore) e <em>catturati<\/em> (viene eseguito il codice per gestire l&#8217;errore). Gli errori <em>non catturati<\/em> causano l&#8217;interruzione dell&#8217;esecuzione dello script Powershell. Incapsulando il codice in blocchi <a href=\"https:\/\/learn.microsoft.com\/en-us\/powershell\/module\/microsoft.powershell.core\/about\/about_try_catch_finally?view=powershell-7.4\" target=\"_blank\" rel=\"noopener\"><strong>try<\/strong>, <strong>catch<\/strong> e <strong>finally<\/strong><\/a>, puoi gestire questo tipo di errori.<\/p>\n<p>Se il codice eseguito in un blocco <strong>try<\/strong> lancia un errore, il blocco di codice nel blocco <strong>catch<\/strong> corrispondente verr\u00e0 eseguito per gestire l&#8217;errore (permettendo all&#8217;esecuzione di continuare, se possibile). Qualsiasi operazione di pulizia che desideri eseguire, indipendentemente dal fatto che si sia verificato o meno un errore, pu\u00f2 essere aggiunta a un blocco <strong>finally<\/strong>. Questo viene spiegato meglio con un esempio di codice completo pi\u00f9 avanti in questa pagina.<\/p>\n<p>La <a href=\"https:\/\/devblogs.microsoft.com\/scripting\/understanding-non-terminating-errors-in-powershell\/\" target=\"_blank\" rel=\"noopener\">gestione degli errori non-terminating<\/a> avviene in modo diverso, poich\u00e9 un errore non viene lanciato per interrompere l&#8217;esecuzione e quindi non pu\u00f2 essere catturato. L&#8217;errore viene invece memorizzato nella variabile <strong>$Error<\/strong>, un array di errori a cui puoi accedere in qualsiasi punto degli script PowerShell per vedere se un&#8217;istruzione precedente ha generato un errore non-terminating, come mostrato in questo esempio:<\/p>\n<p><strong>Get-ChildItem -Path &#8220;C:\\fake_path&#8221;<\/strong><\/p>\n<p><strong>if ($Error) {<\/strong><\/p>\n<p><strong>Write-Host &#8220;Error occurred: $($Error[0])&#8221; # Visualizza l&#8217;errore pi\u00f9 recente come stringa<\/strong><\/p>\n<p><strong>$Error.Clear() # Cancella l&#8217;errore<\/strong><\/p>\n<p><strong>}<\/strong><\/p>\n<p>Sopra, il comando <a href=\"https:\/\/learn.microsoft.com\/en-us\/powershell\/module\/microsoft.powershell.management\/get-childitem?view=powershell-7.4\" target=\"_blank\" rel=\"noopener\">Get-ChildItem<\/a> di PowerShell genera un errore non-terminating se il percorso del filesystem fornito non esiste (in questo caso <strong>C:\\fake_path<\/strong>). L&#8217;errore viene registrato nella variabile $Error, che viene poi controllata e gestita.<\/p>\n<p>Se vuoi assegnare l&#8217;output di errore di un particolare comando a una variabile personalizzata, puoi usare il parametro <strong>-ErrorVariable<\/strong> (tieni presente che in questo caso la variabile error non \u00e8 un array):<\/p>\n<p><strong>Get-ChildItem -Path &#8220;C:\\fake_path&#8221; -ErrorVariable customError<\/strong><\/p>\n<p><strong>if ($customError) {<\/strong><\/p>\n<p><strong>Write-Host &#8220;Error occurred: $customError&#8221; # Visualizza l&#8217;errore come una stringa<\/strong><\/p>\n<p><strong>}<\/strong><\/p>\n<p>Puoi anche trasformare gli errori non-terminating in errori terminating e gestirli con blocchi try\/catch. Lo puoi fare per ogni errore non-terminating incontrato nello script, impostando il parametro globale <a href=\"https:\/\/learn.microsoft.com\/en-us\/powershell\/module\/microsoft.powershell.core\/about\/about_preference_variables?view=powershell-7.4\" target=\"_blank\" rel=\"noopener\"><strong>$ErrorActionPreference<\/strong><\/a> su <strong>Stop<\/strong>:<\/p>\n<p>$ErrorActionPreference = &#8220;Stop&#8221;<\/p>\n<p>Oppure, se vuoi farlo solo per gli errori di un singolo comando, puoi impostare il parametro <strong>-ErrorAction<\/strong>:<\/p>\n<p><strong>Get-ChildItem -Path &#8220;C:\\fake_path&#8221; -ErrorAction Stop<\/strong><\/p>\n<h2>Implementare i blocchi try\/catch\/finally in PowerShell<\/h2>\n<p>Di seguito \u00e8 riportato un esempio di script PowerShell che chiarisce la sintassi e la struttura dei blocchi try\/catch\/finally, e mostra come utilizzare pi\u00f9 blocchi catch per diversi tipi di eccezione e come utilizzare un blocco finally per ripulire e gestire eventuali errori residui. Innanzitutto, ecco un singolo errore gestito con un blocco try\/catch:<\/p>\n<p><strong>try {<\/strong><\/p>\n<p><strong># Tenta di eseguire un\u2019operazione su file che fallisce<\/strong><\/p>\n<p><strong>Get-Content -Path &#8220;C:\\fake_path\\fake_file.txt&#8221; -ErrorAction Stop<\/strong><\/p>\n<p><strong>} catch {<\/strong><\/p>\n<p><strong>Write-Host &#8220;Exception caught: $($_.Exception.Message)&#8221;<\/strong><\/p>\n<p><strong>}<\/strong><\/p>\n<p>Puoi anche gestire pi\u00f9 tipi diversi di potenziali errori in un singolo blocco <strong>try<\/strong>, gestendo ciascuno con il proprio blocco <strong>catch<\/strong>:<\/p>\n<p><strong>try {<\/strong><\/p>\n<p><strong># Ciascuno dei comandi seguenti lancer\u00e0 un errore terminating di tipo diverso<\/strong><\/p>\n<p><strong>Get-Content -Path &#8220;C:\\fake_path\\fake_file.txt&#8221; -ErrorAction Stop # Tentativo di operazione su file che non riesce a lanciare una ItemNotFoundException<\/strong><\/p>\n<p><strong>$null.fakeFunction() # Tentativo di eseguire un metodo inesistente su un oggetto null per lanciare una RuntimeException<\/strong><\/p>\n<p><strong>$divideZero = 1\/0 # Divide per zero per lanciare un&#8217;eccezione che non sar\u00e0 catturata in modo specifico<\/strong><\/p>\n<p><strong>} catch [System.Management.Automation.ItemNotFoundException] { # Cattura l&#8217;errore specifico lanciato da Get-Content<\/strong><\/p>\n<p><strong>Write-Host &#8220;Item not found exception caught: $($_.Exception.Message)&#8221;<\/strong><\/p>\n<p><strong>} catch [System.Management.Automation.RuntimeException] { # Cattura l&#8217;errore specifico lanciato da $null.fakeFunction<\/strong><\/p>\n<p><strong>Write-Host &#8220;Runtime exception caught: $($_.Exception.Message)&#8221;<\/strong><\/p>\n<p><strong>} catch { # Cattura tutti gli altri errori<\/strong><\/p>\n<p><strong># Blocco generale di cattura per qualsiasi altra eccezione<\/strong><\/p>\n<p><strong>Write-Host &#8220;General exception caught: $($_.Exception.Message)&#8221;<\/strong><\/p>\n<p><strong>} finally { # Il blocco finally viene sempre eseguito, indipendentemente dal fatto che sia stata lanciata un&#8217;eccezione o meno.<\/strong><\/p>\n<p><strong>Write-Host &#8220;Executing the finally block.&#8221;<\/strong><\/p>\n<p><strong>$Error.Clear() # Questo potrebbe essere usato, per esempio, per ripulire gli errori non-terminating.<\/strong><\/p>\n<p><strong>}<\/strong><\/p>\n<p>Lo scopo di ogni istruzione \u00e8 spiegato nel codice, in modo da permetterti di vedere il contesto completo di come le istruzioni <strong>try<\/strong>, <strong>catch<\/strong> e <strong>finally<\/strong> lavorano insieme. Tieni presente che se si verificano pi\u00f9 errori terminating nello stesso blocco <strong>try<\/strong>, solo il primo errore verr\u00e0 catturato e gestito, e poi verr\u00e0 eseguito il blocco <strong>finally<\/strong>. Una volta risolto questo errore, gli errori successivi verranno catturati durante l&#8217;esecuzione dello script.<\/p>\n<h2>Tecniche avanzate di gestione degli errori PowerShell ed esempi<\/h2>\n<p>\u00c8 anche possibile annidare i blocchi try\/catch, in modo che gli errori &#8220;salgano&#8221; attraverso di essi. Ci\u00f2 ti consente di gestire errori specifici nei blocchi try\/catch interni e di gestire qualsiasi errore non catturato o rilanciato, anche quelli all&#8217;interno dei blocchi <strong>catch<\/strong> interni, nei blocchi esterni. Per esempio, potresti usare blocchi annidati per gestire errori specifici e poi usare un singolo blocco esterno per catturare e registrare tutti gli errori, invece di ripetere il codice per registrarli in ogni blocco interno.<\/p>\n<p><strong>try { # Inizio del blocco esterno di cattura<\/strong><\/p>\n<p><strong>try { # Inizio del blocco interno di cattura<\/strong><\/p>\n<p><strong># Inserisci qui il codice potenzialmente causa di errori<\/strong><\/p>\n<p><strong>Get-Content -Path &#8220;C:\\fake_path\\fake_file.txt&#8221; -ErrorAction Stop<\/strong><\/p>\n<p><strong>} catch [System.Management.Automation.ItemNotFoundException] { # Dichiarazione di catch per il blocco catch interno che gestisce specificamente ItemNotFoundException<\/strong><\/p>\n<p><strong>Write-Host &#8220;Inner try block file not found exception caught: $($_.Exception.Message)&#8221;<\/strong><\/p>\n<p><strong>} catch { # Dichiarazione di cattura per il blocco catch interno che gestisce tutte le altre eccezioni<\/strong><\/p>\n<p><strong>Write-Host &#8220;Inner try block exception caught: $($_.Exception.Message)&#8221;<\/strong><\/p>\n<p><strong>throw # Lancia nuovamente l&#8217;eccezione, in modo che arrivi al blocco try\/catch esterno<\/strong><\/p>\n<p><strong>}<\/strong><\/p>\n<p><strong>} catch { # Dichiarazione di cattura per il blocco catch esterno<\/strong><\/p>\n<p><strong>Write-Host &#8220;Outer try block exception caught: $($_.Exception.Message)&#8221; # Gestisce tutti gli errori rilanciati nei blocchi interni di catch qui per le attivit\u00e0 di pulizia, registrazione e avviso<\/strong><\/p>\n<p><strong>}<\/strong><\/p>\n<p>Nell&#8217;esempio precedente, l&#8217;<strong>eccezione ItemNotFoundException<\/strong> non viene rilanciata, quindi non verr\u00e0 catturata dal blocco catch esterno.<\/p>\n<p>Quando iniziani a espandere gli script PowerShell per coprire i tuoi specifici casi d&#8217;uso, \u00e8 probabile che tu voglia essere in grado di introdurre eccezioni e <a href=\"https:\/\/learn.microsoft.com\/en-us\/powershell\/scripting\/developer\/cmdlet\/windows-powershell-error-records?view=powershell-7.4\" target=\"_blank\" rel=\"noopener\">record di errore<\/a>PowerShell personalizzati:<\/p>\n<p><strong>try {<\/strong><\/p>\n<p><strong>$customException = New-Object Exception &#8220;This is a custom error!&#8221; # Crea e lancia un errore personalizzato<\/strong><\/p>\n<p><strong># Crea un record di errore personalizzato<\/strong><\/p>\n<p><strong>$customErrorRecord = New-Object System.Management.Automation.ErrorRecord (<\/strong><\/p>\n<p><strong>$customException,<\/strong><\/p>\n<p><strong>&#8220;CustomErrorID&#8221;,<\/strong><\/p>\n<p><strong>[System.Management.Automation.ErrorCategory]::NotSpecified, # Imposta la categoria ErrorRecord a NotSpecified<\/strong><\/p>\n<p><strong>$null # Non specifica un oggetto di destinazione specifico per questo errore<\/strong><\/p>\n<p><strong>)<\/strong><\/p>\n<p><strong>throw $customErrorRecord<\/strong><\/p>\n<p><strong>} catch {<\/strong><\/p>\n<p><strong># Cattura e gestisce il record di errore personalizzato<\/strong><\/p>\n<p><strong>Write-Host &#8220;Error Message: $($_.Exception.Message)&#8221;<\/strong><\/p>\n<p><strong>Write-Host &#8220;Error ID: $($_.FullyQualifiedErrorId)&#8221;<\/strong><\/p>\n<p><strong>}<\/strong><\/p>\n<p>Sopra, puoi notare che non \u00e8 stato specificato alcun oggetto di destinazione (poich\u00e9 \u00e8 impostato su <strong>$null<\/strong>). Potresti invece sostituirlo con un percorso di file o un altro riferimento e aggiungere ulteriori dettagli al testo dell&#8217;eccezione per rendere l&#8217;errore personalizzato pi\u00f9 informativo.<\/p>\n<h2>Le best practice nella gestione degli errori PowerShell<\/h2>\n<p>Esistono diverse best practice da seguire quando scrivi gli script PowerShell, per garantire una gestione efficace degli errori:<\/p>\n<ul>\n<li><strong>Scrivi messaggi di errore chiari e prevedibili<\/strong>: I messaggi di errore devono essere descrittivi e includere sufficienti dettagli, dall\u2019<a href=\"https:\/\/learn.microsoft.com\/en-us\/powershell\/scripting\/developer\/cmdlet\/interpreting-errorrecord-objects?view=powershell-7.4\" target=\"_blank\" rel=\"noopener\">oggetto Exception o ErrorRecord<\/a> per identificare la causa specifica di un errore.<\/li>\n<li><strong>Assicurati che gli script possano continuare a funzionare (o a uscire in modo pulito) se si verifica un errore<\/strong>: Se i tuoi script stanno eseguendo altre attivit\u00e0, potresti voler gestire l&#8217;errore mentre continuano. Gli errori che impediscono allo script di continuare dovrebbero causare l&#8217;uscita dello script con un <a href=\"https:\/\/devblogs.microsoft.com\/powershell\/windows-powershell-exit-codes\/\" target=\"_blank\" rel=\"noopener\">codice di uscita<\/a> e il risultato di qualsiasi errore dovrebbe essere registrato e riportato.<\/li>\n<li><strong>Verifica regolarmente la tua infrastruttura di gestione degli errori e di reporting<\/strong>: Gli automatismi di PowerShell sono inutili se falliscono senza che tu te ne accorga. Testa regolarmente i tuoi script introducendo errori per assicurarti che la gestione degli errori funzioni, che i dettagli siano registrati e che tu riceva avvisi.<\/li>\n<\/ul>\n<p>La gestione degli errori \u00e8 una caratteristica importante dello scripting PowerShell ed \u00e8 utile per sviluppare le tue capacit\u00e0 di scripting e automazione. L&#8217;implementazione corretta della gestione degli errori, compreso il lancio corretto degli errori, l&#8217;uso di blocchi try\/catch\/finally e l&#8217;utilizzo di $ErrorActionPreference, ti aiuter\u00e0 a <a href=\"https:\/\/www.ninjaone.com\/it\/blog\/elenco-di-comandi-essenziali-di-windows-powershell\" target=\"_blank\" rel=\"noopener\">padroneggiare la sintassi di PowerShell<\/a> e a comprendere meglio i problemi incontrati dagli script, aiutandoti cos\u00ec a gestirli meglio.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>PowerShell \u00e8 il principale linguaggio di scripting e riga di comando utilizzato dai sistemi operativi Windows. Consente di eseguire programmi e attivit\u00e0 di gestione del sistema da terminale ed \u00e8 ampiamente utilizzato da amministratori di sistema e sviluppatori per automatizzare i loro flussi di lavoro. La gestione degli errori \u00e8 una parte importante di qualsiasi [&hellip;]<\/p>\n","protected":false},"author":89,"featured_media":269617,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_relevanssi_hide_post":"","_relevanssi_hide_content":"","_relevanssi_pin_for_all":"","_relevanssi_pin_keywords":"","_relevanssi_unpin_keywords":"","_relevanssi_related_keywords":"","_relevanssi_related_include_ids":"","_relevanssi_related_exclude_ids":"","_relevanssi_related_no_append":"","_relevanssi_related_not_related":"","_relevanssi_related_posts":"","_relevanssi_noindex_reason":"","_lmt_disableupdate":"no","_lmt_disable":"","footnotes":""},"categories":[4354],"tags":[],"class_list":["post-276233","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-operazioni-it"],"acf":[],"modified_by":"Sergio Oricci","_links":{"self":[{"href":"https:\/\/www.ninjaone.com\/it\/wp-json\/wp\/v2\/posts\/276233","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ninjaone.com\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ninjaone.com\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ninjaone.com\/it\/wp-json\/wp\/v2\/users\/89"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ninjaone.com\/it\/wp-json\/wp\/v2\/comments?post=276233"}],"version-history":[{"count":0,"href":"https:\/\/www.ninjaone.com\/it\/wp-json\/wp\/v2\/posts\/276233\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.ninjaone.com\/it\/wp-json\/wp\/v2\/media\/269617"}],"wp:attachment":[{"href":"https:\/\/www.ninjaone.com\/it\/wp-json\/wp\/v2\/media?parent=276233"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ninjaone.com\/it\/wp-json\/wp\/v2\/categories?post=276233"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ninjaone.com\/it\/wp-json\/wp\/v2\/tags?post=276233"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}