Powershell et les systèmes de logs – Partie 1

Lorsque nous créons des scripts, rien ne permet de contrôler sa correcte exécution, si ce n’est de partir dans une campagne de tests longue et coûteuse. C’est pourquoi, il est important d’implémenter des logs dans ses scripts, sous forme de fichier, dans les eventlog Windows, dans une base de données, etc…

Plusieurs approches sont possibles, la plus ambitieuse serait d’utiliser Event Tracing for Windows (ETW), Log4Net offre énormément de possibilités, l’utilisation de la classe WMI win32_NTLogEvent est aussi une solution, mais je vais m’attarder sur les Eventlog de Windows ainsi que sur l’écriture d’un fichier de log. ETW, s’approche énormément du développement, ce qui n’est pas mon but, en tout cas, pas sur ce blog. Et pour l’utilisation de Log4Net, notre ami Laurent, demi dieu français du Powershell nous à concocter une splendide doc sur son fonctionnement, vous la trouverez ici. Ce framework permet de “multithreader” l’écriture de log, si vous utilisez des Jobs Powershell par exemple…

Commençons donc à regarder comment fonctionne Get-WinEvent en allant regarder la Technet et The Scripting Guy…  On s’aperçoit que la classe retournée est System.Diagnostics.EventLogEntry.

En ce qui concerne Get-EventLog (Page technet et The Scripting Guy) il retourne les résultats de la classe System.Diagnostics.Eventing.Reader.EventLogRecord.

On note quelques différences sur les termes employés, mais pas vraiment de révolution, ah si ! Get-EventLog n’est pas disponible sur PSv1… La partie la plus intéressante avec le cmdlet Get-EventLog réside dans le fait qu’il soit normalement bien plus rapide, en effet il effectue les filtrages avant d’envoyer le résultat de la commande. Imaginez en remote sur un réseau, le gain de temps que cela peut représenter sur des logs système.

Vous me direz, c’est bien beau mais nous on veut écrire nos actions dans les EventLog de Windows, oui, oui j’y viendrais plus tard.  Je faisais un petit tour du propriétaire et vais d’abord m’attarder sur la création d’un fichier de log classique.

Il fallait bien une base pour cette série d’article sur les logs et powershell. J’ai donc choisis de vous proposez une petite fonction perso qui est présente dans tous mes scripts.

[powershell]

function Write-Log {
param(
[Parameter(Mandatory=$true)] [Int]$id,
[Parameter(Mandatory=$true)] [ValidateSet(“ERROR”,”SUCCESS”,”WARNING”)] [string]$Status,
[Parameter(Mandatory=$true)] [String]$date,
[Parameter(Mandatory=$false)] [String]$logfile = “C:loglog.txt”,
[Parameter(Mandatory=$false)] [String]$server = $env:computername
)

$msg = $Reason.$id

#echo “$CurrentDate $server : $Status : $msg” >> $logfile

if ($Status -eq “ERROR”) {
Write-Error -Message “$CurrentDate $server : $Status : $msg”
if ($error) {
$error >> $logfile
$error.clear()
}
exit $id
}
elseif ($Status -eq “WARNING”) {
Write-Warning -Message “$CurrentDate $server : $Status : $msg”
}
else {
Write-Verbose -Message “$CurrentDate $server : $Status : $msg”
}
}

[/powershell]

Pour utiliser cette fonction dans votre script, vous pouvez utiliser le try/catch qui va permettre de tester  chaque action et de détecter facilement une erreur.

[powershell]

$Reason = @{
1=”reason1″
2=”reason2″
3=”reason3″
4=”reason4″
5=”reason5″
6=”reason6″
#etc…
}

try {

Get-Service
Write-Log -id 1 -Status SUCCESS -date (date -format g)
}
catch {
Write-Log -id 1 -Status ERROR -date (date format g)
}

[/powershell]

 

L’utilité de cette fonction réside dans le fait qu’elle va vous permettre de stocker les erreurs powershell dans votre fichier de logs et d’inverstiguer en cas de besoin.

Dans la prochaine partie, on va s’attacher à rajouter des écritures dans les EventLogs Windows, ainsi que l’envoit de ces logs par mail histoire de faire une fonction propre et qui pourrait vous être utile !

@+