Powershell: Comment puis-je empêcher l'affichage des erreurs dans un script?

92

Lorsque mon script PowerShell essaie, par exemple, de créer un objet SQL Server pour un serveur qui n'existe pas («bla» dans mon cas), PowerShell affiche de nombreuses erreurs PowerShell en rouge.

Étant donné que mon script vérifie la valeur de $?après de tels appels et affiche et enregistre les erreurs, je préfère ne pas afficher les plusieurs lignes d'erreurs PowerShell.

Comment puis-je désactiver ceux affichés pour mon script?

Andrew J. Brehm
la source

Réponses:

132

Vous avez plusieurs options. Le plus simple consiste à utiliser les ErrorActionparamètres.

-Erroractionest un paramètre universel pour toutes les applets de commande. S'il y a des commandes spéciales que vous voulez ignorer, vous pouvez utiliser -erroraction 'silentlycontinue'qui ignorera fondamentalement tous les messages d'erreur générés par cette commande. Vous pouvez également utiliser la Ignorevaleur (dans PowerShell 3+):

Contrairement à SilentlyContinue, Ignore n'ajoute pas le message d'erreur à la variable automatique $ Error.

Si vous souhaitez ignorer toutes les erreurs d'un script, vous pouvez utiliser la variable système $ErrorActionPreferenceet faire la même chose:$ErrorActionPreference= 'silentlycontinue'

Voir about_CommonParameters pour plus d'informations sur -ErrorAction. Voir about_preference_variables pour plus d'informations sur $ ErrorActionPreference.

JNK
la source
avez-vous besoin d'un guillemet simple dans -erroraction «continue silencieusement»? Intellisese affiche des options et n'ajoute pas de guillemet simple.
PAS
1
Si le format ci-dessus ne fonctionne pas pour vous, reportez-vous au lien fourni ci-dessus. J'ai dû formater comme -ErrorAction:SilentlyContinuedans PS 5.1. J'appelais ma cmdlet à partir d'un lot, donc je ne sais pas si cela fait une différence. Mais de bonnes informations lorsque vous savez qu'une erreur acceptable peut être générée.
David
--rm. \ Windows.old \ -Force -Recurse -Verbose -ErrorAction SilentlyContinue -WarningAction SilentlyContinue </code>
Tertius Geldenhuys
18

Windows PowerShell fournit deux mécanismes pour signaler les erreurs: un mécanisme pour mettre fin aux erreurs et un autre mécanisme pour les erreurs sans fin .

Le code CmdLets interne peut appeler une ThrowTerminatingErrorméthode lorsqu'une erreur se produit qui n'autorise pas ou ne doit pas permettre à l'applet de commande de continuer à traiter ses objets d'entrée. Le scripteur peut utiliser une exception pour intercepter ces erreurs.

EX:

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

Le code CmdLets interne peut appeler une WriteErrorméthode pour signaler des erreurs sans fin lorsque l'applet de commande peut continuer à traiter les objets d'entrée. Le rédacteur de script peut ensuite utiliser l'option -ErrorAction pour masquer les messages, ou utiliser $ErrorActionPreferencepour configurer l'ensemble du comportement du script.

JPBlanc
la source
8

J'ai eu un problème similaire en essayant de résoudre les noms d'hôtes en utilisant [system.net.dns]. Si l'adresse IP n'a pas été résolue, .Net a généré une erreur de fin. Pour éviter l'erreur de fin et conserver le contrôle de la sortie, j'ai créé une fonction à l'aide de TRAP.

PAR EXEMPLE

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

Vous êtes loin d'être sur la bonne voie ici.

Vous avez déjà un gros message d'erreur. Pourquoi diable voudriez-vous écrire du code qui vérifie $?explicitement après chaque commande ? C'est extrêmement lourd et sujet aux erreurs. La bonne solution est d' arrêter de vérifier$? .

Au lieu de cela, utilisez le mécanisme intégré de PowerShell pour exploser à votre place. Vous l'activez en définissant la préférence d'erreur sur le niveau le plus élevé:

$ErrorActionPreference = 'Stop'

Je mets cela en haut de chaque script que j'écris, et maintenant je n'ai plus à vérifier $?. Cela rend mon code beaucoup plus simple et plus fiable.

Si vous rencontrez des situations dans lesquelles vous avez vraiment besoin de désactiver ce comportement, vous pouvez soit catchl'erreur, soit transmettre un paramètre à une fonction particulière à l'aide du Common -ErrorAction. Dans votre cas, vous souhaitez probablement que votre processus s'arrête à la première erreur, détecte l'erreur, puis enregistre-la.

Notez que cela ne gère pas le cas où les exécutables externes échouent (code de sortie différent de zéro, par convention), vous devez donc toujours vérifier $LASTEXITCODEsi vous en appelez. Malgré cette limitation, le paramètre économise encore beaucoup de code et d'efforts.

Fiabilité supplémentaire

Vous pouvez également envisager d'utiliser le mode strict :

Set-StrictMode -Version Latest

Cela empêche PowerShell de continuer silencieusement lorsque vous utilisez une variable inexistante et dans d'autres situations étranges. (Voir le -Versionparamètre pour plus de détails sur ce qu'il restreint.)

La combinaison de ces deux paramètres rend PowerShell beaucoup plus de langage à échec rapide, ce qui facilite grandement la programmation.

jpmc26
la source
2

Ajoutez -ErrorAction SilentlyContinueà votre script et vous serez prêt à partir.

Jayant Rajwani
la source
2

Dans certains cas, vous pouvez diriger après la commande un Out-Null

command | Out-Null
Baie
la source
-1

Si vous voulez que le message d'erreur PowerShell pour une applet de commande soit supprimé, mais que vous voulez quand même attraper l'erreur, utilisez "-erroraction 'silentlyStop'"

Mikkel Vejlby
la source
Il n'y a pas une telle action. Bien qu'il y ait une action Stop.
Marvin Dickhaus
Mais cela permet de supprimer le message d'erreur rouge et d'utiliser toujours la commande / section catch lors de l'utilisation de New-Item -ItemType directory(PowerShell v2.0)
Milan Kerslager
@MilanKerslager pourriez-vous montrer un exemple de code - puisque moi, et tout le monde, je crois qu'il n'y a pas d'ActionPreference comme 'SilentlyStop'
FSCKur
Je suis raisonnablement convaincu que Mikkel voulait dire SilentlyContinue plutôt que silencieusementStop, car cela a beaucoup plus de sens dans le contenu de ce que vous voulez qu'il fasse.
John