Share via


S'assurer de la bonne exécution des scripts powershell

Vous créez des scripts powershell à la pelle?
Vous déployer les scripts sur des dizaines de machines?
Vous passez votre temps à éplucher des logs à la recherche d'erreur ?
Vous devez restaurer un backup mais venez de vous apercevoir que la sauvegarde ne fonctionne plus depuis que quelqu'un à modifié les permissions d'un répertoire ?

Ce qui suit pourrait vous intéresser ...

Afin de rester informé de la moindre erreur d’exécution j'ai pris pour habitude "d'encapsuler" mes scripts dans le template ci dessous.

Basiquement le script demande à powershell de traiter la moindre erreur comme étant bloquante afin que celle-ci puisse être interceptée en utilisant la structure try{}catch{}.  
La gestion de l'erreur peut ensuite être personnalisée à votre guise (envoi d'email, écriture d'un évènement windows, envoi d'une requête http etc.)

# Template.ps1# abstract: traiter toutes les erreurs comme blocantes, envoyer un mail et écrire dans le journal en cas d'erreur# [CmdletBinding()]param()  # GENERATION D'UNE TRACE POUR LE DEBUGGAGE#########################################$erroractionPreference="stop" #toutes les erreurs seront considérées bloquantes$trace="$env:temp\trace$(get-date -f yyMMddHHmmss).txt"try{stop-transcript -ea silentlycontinue }catch{} #suppression d'une éventuelle trace antérieure non terminéestart-transcript -path $trace -force #démarrage de la trace # VARIABLES PRIVEES#####################$_scriptpath=$MyInvocation.myCommand.definition #chemin complet du script$_scriptname=$MyInvocation.myCommand.name #nom du script  #    *** !!  VARIABLES A MODIFIER  !! ***###########################################$logdir="c:\logs"$description="test du template de gestion des erreurs" #la description sera réutilisée dans les messages logs et mails $message="Erreur : $description ($_scriptpath)" #sujet des mails$from="$env:computername@$env:userdomain" #expediteur pour mail$to="user@domain.com","user2@dom.com" #destinataires des mails$PSEmailServer="127.0.0.1" #adresse du serveur smtp$_enc=[system.text.encoding]::UTF8 #jeu de caractères à utiliser pour le mail #      *** DEBUT DU SCRIPT  ***################################# get-date"Début du script" try{   ###    !!!  VOTRE CODE ICI   !!!   ###     $source="c:\temp\test.csv"    $destination="\\azerty\uiop\" #serveur inexistant -> génerera une erreur     copy-item $source $destination  }  catch{     ###    !!!  VOTRE TRAITEMENT D'ERREUR ICI   !!!   ###    write-host "Une erreur est survenue !"    $_.Exception.toString() #affiche l'exception qui a été intercptée    $_.ScriptStackTrace.toString()     get-date    " !!! FIN ANORMALE !!!"     # on ne peut pas envoyer le fichier tant que la trace n'est pas terminée, on en fait donc une copie    $attachment= $logdir+"\trace_"+$myinvocation.mycommand.name+".txt" -replace " ","_"    copy-item $trace $attachment -force      $eventsource="powershellmonitor" #nom de la souce de l'événment windows     #Création de la source dans le journal si elle n'existe pas !nécessite des privilèges administrateur    if ([System.Diagnostics.EventLog]::SourceExists($eventsource) -eq $false) {        [System.Diagnostics.EventLog]::CreateEventSource($eventsource, "Application")    }     $msg=$message + $($_.Exception.Message)+$($_.scriptStackTrace)    Write-EventLog application -EntryType error -Source powershellmonitor -eventID 1 -Message $msg    send-mailmessage  -encoding $_enc -subject $message -bodyasHTML  $msg -to $to -from $from -attachments $attachment      stop-transcript    break} get-date"Fin normale du script"stop-transcript 
Exemple de mail envoyé :

avec la trace en pièce jointe

Ce template m'a déjà permis pas mal de fois de corriger des problèmes qui seraient certainement passés inaperçus autrement.
Attention tout de même, le script n'interceptera pas les erreurs de logique comme les boucles infinies.
 D'ailleurs si quelqu'un voit comment définir un temps d'exécution maximal, qu'il n'hésite pas à ajouter un commentaire.

http://c.statcounter.com/9971548/0/4d58d7f8/1/