10 nov. 2012

[snippet] Script d'alerte de d'indisponibilité de serveur

Un petit script Powershell qui vérifie si les machines spécifiées (dans un fichier texte par exemple) répondent, et si une machine ne répond pas, un mail d'alerte est automatiquement envoyé avec un rapport. Il suffit ensuite de créer une tâche planifiée s'exécutant toutes les 10 minutes...

Voici le script powershell :

# ce script sert à vérifier l'état des tâches sauvegardes
# et d'envoyer un mail rapport à la fin
# ci-dessous la configuration de l'envoie de mail

$expediteur = "Opérateur de sécurité"

$destinataire = "admin1@domaine.tld,admin2@domaine.tld" # séparer entre virgule

$serveur = "srv-exchange.domaine.tld"

$objet = "Message alerte disponibilité quotidienne " + [System.DateTime]::Now

# ci-dessous la configuration du fichier de log

$log = "verifDispo.txt"

############################ NE RIEN MODIFIER CI-DESSOUS ######################

echo "Tâche en cours..."
$dateStartRapport = date
$data = "Nom".PadRight(20)+"État`n"
$data += '-'.PadRight(20-1,'-')+' '+'-'.PadRight(7-1,'-')
$countOK = 0
$count = 0

if($args.length -eq 1 -and $args[0] -ine "-help") {
    $file = $args[0]
}
else {
    $file = "dispo.txt"
}


foreach ($srv in Get-Content $file)
{
    if($srv -ne "") {
        $count++
        $line = "`n"+$srv.PadRight(20)
        if($srv.StartsWith('#')) {
            $line += "Ignoré"
            $countOk++
        }
        else {
            ping -n 1 -w 1000 $srv | Out-Null
            if($?) {
                $line += "Ok"
                $countOk++
            }
            else {
                $line += "Erreur"
            }
        }
        $data += $line
    }
}

$rapport = "Rapport de disponibilité " + $dateStartRapport
$rapport += "`nRésumé: $countOk/$count OK en "+((Get-Date) - $dateStartRapport).minutes.ToString().PadLeft(3)+" minutes, terminé à $(Get-Date)"
$rapport += "`n`n$data"
$rapport += "`n`nTerminé"
$rapport >> $log
if($count -ne $countOk) {
    # envoie du mail
    $message = new-object System.Net.Mail.MailMessage $expediteur, $destinataire, $objet, $rapport
    $message.Priority = "High"
    $client = new-object System.Net.Mail.SmtpClient $serveur
    $client.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
    $client.Send($message)
    if($?) { "Mail envoyé avec succès à $destinataire" >> $log }
    else { "Mail erreur pour $destinataire" >> $log }
}
else { "Mail non envoyé" >> $log }

Le script est très simpliste. Il ne vérifie pas l'état des services. Donc si le firewall du serveur (ou poste client !) est configuré pour ne pas répondre aux pings, cela ne fonctionnera pas. D'ailleurs, si un serveur subit une usurpation d'IP, ça ne sera pas détecté non plus. Evidemment, si c'est le serveur de messagerie qui ne répond plus, vous ne risquez pas de recevoir l'alerte non plus...