Envoyer un email si un script PowerShell obtient des erreurs à tous et terminer le script
Quelque chose que j'ai pensé à récemment, et j'aimerais avoir quelques commentaires de la bonnes gens de Débordement de Pile.
Je lance un assez grand nombre de scripts PowerShell sur différents horaires (à l'aide du Planificateur de Tâches). Ces scripts généralement de recueillir des données et de les stocker dans des tables SQL pour moi. Je dirais que je suis en cours d'exécution de 40 à 50 scripts ou donc pour le moment, peut-être plus.
Seule chose que j'ai sérieusement envisagé récemment, c'est le meilleur moyen de:
- De s'assurer que si des erreurs se produisent le script se termine sans autre traitement.
- Le script doit également m'envoyer un email en cas d'échec à l'exception des détails, en me montrant dans quelle mesure il a obtenu.
- La transcription/le progrès est enregistré donc je peut passer en revue toutes les erreurs et d'essayer de mieux les gérer dans le script.
Cela va être juste un peu de travail à faire, donc j'aimerais y aller avec la bonne approche, dès le début.
La seule façon que je peux voir de la réalisation de quelque chose qui serait de faire ce qui suit:
$ErrorActionPreference "Stop"
Ce qui devrait entraîner des exceptions à déclencher un bloc Try/Catch.
Exécuter le script en entier dans un Try/Catch/finally bloc.
Bloc finally est facultatif bien sûr. Quelque chose comme ceci:
$ErrorActionPreference = "Stop"
Try
{
$Content = gc "C:\Temp\NonExistentFile.txt"
foreach ($Line in $Content)
{
Write-Host $Line
}
}
Catch
{
Write-Host $_ -ForegroundColor "Red" -BackgroundColor "Black"
break
}
Journal de la "Transcription" de Données en HTML et envoyez le contenu en cas d'échec.
J'ai essayé quelques façons de l'exploitation forestière, et l'une des clés de choses pour moi, c'est que je veux quelque chose qui est:
- Facile pour vous connecter en fournissant le texte, et un emplacement du fichier journal.
- Comprend la Date et l'Heure au début de chaque ligne du fichier de log.
J'ai commencé l'écriture d'un texte .les fichiers txt, mais c'était un peu de travail à faire.
Start-Transcription a été OK, mais ne comprennent pas la date/l'heure sur chaque ligne.
J'ai eu un certain succès avec une Fonction personnalisée qui ferait de Démarrage de la Transcription, et d'écrire n'importe quel texte que j'ai envoyé en en Write-Host, avec la date et l'heure au début de chaque ligne.
Mais finalement, je pense que ce dont j'ai besoin pour cela de vous connecter en un .document html, et puis l'envoyer par courriel le contenu de ce si une erreur se produit. Quelque chose comme ceci par exemple:
Function Send-ErrorEmail
{
Write-Host "Would Send Email Here" -ForegroundColor "Magenta"
}
Function Write-Html
{
[CmdletBinding()]
param
(
[Parameter(ValueFromPipeline=$True)]$Text,
$HTMLTag
)
[string]$CurrentDateTime = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss - ")
switch ($HTMLTag)
{
"h1" {$ReturnText = ("<h1>" + $Text + "</h1>")}
"h2" {$ReturnText = ("<h2>" + $Text + "</h2>")}
default {$ReturnText = ("<p>" + $CurrentDateTime + $Text + "</p>")}
}
Write-Host -ForegroundColor "Yellow" ($CurrentDateTime + $Text)
return $ReturnText
}
$ErrorActionPreference = "Stop"
Try
{
#Stores the HTML File
$LogfilePath = "C:\Temp\LogFile.html"
#Begin HTML
$HTML = @()
$HTML += "<html><head></head><body>"
$HTML += "Begin Script" | Write-Html
#Loop through Computers
$Computers = "LocalHost", "DoesNotExist", "127.0.0.1"
foreach ($Computer in $Computers)
{
#Get Services
$HTML += "Computer: $Computer" | Write-Html -HTMLTag "h1"
$Services = Get-Service -Computer $Computer
$HTML += $Services | ConvertTo-Html -Fragment
}
#Complete HTML
$HTML += "Script End" | Write-Html
$HTML += "</body></html>"
$HTML | Out-File $LogfilePath
}
Catch
{
#Add Exception to HTML
$HTML += $_ | Out-String | Write-Html
#Complete HTML
$HTML += "</body></html>"
$HTML | Out-File $LogfilePath
#Send EMail
Send-ErrorEmail
#Exit Script
exit
}
Toute pensée? Les améliorations que vous pensez que je pourrais faire? Évidemment, le document HTML est laid sans CSS mise en forme et envoi de Courrier de la fonction ne fait rien, mais il semble être le moyen le plus simple pour faire ce que je veux.
Je peux bien sûr dot source de toutes les fonctions parmi tous mes scripts pour faciliter la modification d'une adresse électronique de notification ou similaire.
OriginalL'auteur HungryHippos | 2013-01-09
Vous devez vous connecter pour publier un commentaire.
Global d'erreur de manipulation, je préfère utiliser un piège à déclaration.
Et si vous voulez caution sur une erreur, alors oui,
$ErrorActionPreference
àStop
.J'ai l'habitude de ne jamais utiliser un piège de manière interactive, mais vous pouvez le faire fonctionner en le mettant dans un champ autre que la portée mondiale par exemple, l'exécution de cette manière interactive:
& { trap { "error trapped !!"; continue }; throw "oops" }
Merci de Keith, et bien j'ai juste changé la façon dont j'ai testé le script un peu si je pouvais utiliser le Piège {} à la place. Semble très bien fonctionner pour moi, et mieux de déclarer qu'une seule fois dans le script plutôt que d'avoir à envelopper le tout dans un Try/Catch je pense. La principale chose qui me manque sur les scripts de test de manière interactive est la capacité d'inspecter les variables pour les champs/de données à intervalles réguliers. Je vais marquer votre réponse comme une réponse maintenant.
Merci à vous deux!
OriginalL'auteur Keith Hill