16/05/2024

PowerShell

Comment utiliser PowerShell pour créer un événement dans un journal Windows ?

I. Présentation

Dans ce tutoriel, nous allons exploiter PowerShell pour créer un journal personnalisé et des événements personnalisés dans l'Observateur d'événements de Windows ou Windows Server, à l'aide de deux cmdlets : New-EventLog et Write-EventLog. En complément, nous verrons comment utiliser la classe .NET "EventLog" pour créer des entrées avancées.

Sur Windows, le système d'exploitation, les composants et les applications peuvent générer des événements qui sont inscrits dans les différents journaux centralisés dans l'Observateur d'événements. Ces journaux sont une mine d'informations pour les administrateurs systèmes, mais aussi pour les équipes en charge de la sécurité : une action suspecte peut être consignée dans un événement, qui représentera alors une trace intéressante.

L'intérêt ensuite est de collecter ces événements dans un puits de logs ou un SIEM afin de les analyser et de détecter les comportements suspects ou les anomalies sur une infrastructure.

Grâce à la commande Write-EventLog ou à l'utilisation de la classe EventLog, nous pouvons alimenter les journaux de Windows avec des événements personnalisés qui, eux aussi, pourront être exploités par une solution telle qu'un SIEM. Autrement dit, votre script PowerShell pourra créer des événements contenant les informations de votre choix.

Remarque : avant de pouvoir utiliser Write-EventLog, cette action était possible sous Windows grâce à l'utilisation de l'utilitaire en ligne de commande EVENTCREATE.exe.

II. Utiliser le cmdlet New-EventLog

Au sein de l'Observateur d'événements, vous pouvez créer un journal personnalisé, associé au nom de votre choix, à condition que celui-ci ne soit pas déjà utilisé. Cette étape est facultative, car nous pouvons créer des enregistrements dans certains journaux natifs, notamment dans le journal "Applications" de Windows.

Néanmoins, le fait de créer un journal personnalisé et d'y inscrire par la suite nos propres événements, permet "d'isoler" nos événements personnalisés. Ceci peut vouloir dire également qu'il faudra adapter la configuration de votre outil de collecte de log pour qu'il prenne en charge ce nouveau journal.

La commande suivante permet de créer un journal nommé "PowerShell-Demo", qui accepte deux sources : "Script-1" et "Script-2". Vous pouvez en ajouter autant que vous le souhaitez, et, vous pouvez ajouter des sources supplémentaires à un journal existant. Ceci est indispensable, car chaque événement de journal doit être associé à une source.

New-EventLog -LogName "PowerShell-Demo" -Source "Script-1","Script-2"

Ce journal sera immédiatement visible dans l'Observateur d'événements sous "Journaux des applications et des services".

PowerShell - New-EventLog

D'ailleurs, pour ajouter une source supplémentaire, il suffit d'exécuter une nouvelle fois New-EventLog en indiquant le nom du journal et le nom de la source supplémentaire à ajouter. Voici un exemple pour ajouter la source "Script-3" :

New-EventLog -LogName "PowerShell-Demo" -Source "Script-3"

Si vous effectuez une erreur, par exemple, dans le nom de votre journal, sachez que vous pouvez le supprimer avec cette commande :

Remove-EventLog -LogName "PowerShell-Demo"

Pour approfondir l'utilisation de ce cmdlet, vous pouvez consulter cette page :

III. Utiliser le cmdlet Write-EventLog

Désormais, nous allons voir comment écrire un nouvel événement dans le journal d'événements que nous venons de créer. Nous pourrions aussi l'ajouter dans un autre journal (attention, certains sont protégés), tout se joue au niveau du paramètre "-LogName" de la commande Write-EventLog puisqu'il permet de préciser le journal cible.

Comme pour les autres cmdlets PowerShell, vous pouvez spécifier le nom du cmdlet suivi de chaque paramètre et de sa valeur, mais dans le cas présent, l'écriture proposée ci-dessous permet d'avoir une meilleure lisibilité.

$Event = @{
    LogName = "PowerShell-Demo"
    Source = "Script-1"
    EntryType = "Error"
    EventId = 10000
    Message = "Cette alerte a été généré depuis PowerShell"
}

Write-EventLog @Event

Ce bout de code va créer un événement de type "Erreur" dans notre journal, associé à la source "Script-1" et l'ID "10000". Il contiendra le message "Cette alerte a été généré depuis PowerShell", comme vous pouvez le voir sur l'image ci-dessous. Essayez d'utiliser des ID différents pour vos types d'événements, et évitez aussi d'utiliser des ID déjà utilisé par Windows.

PowerShell - Write-EventLog

À la place du type "Error" permettant de générer une erreur, vous pouvez utiliser les valeurs suivantes : Warning, Informational, SuccessAudit, et FailureAudit. Sachez que cette commande prend en charge le paramètre "-ComputerName", ce qui permet de créer un événement dans le journal d'un ordinateur distant.

Pour consulter ce journal personnalisé, ou un autre journal, vous pouvez utiliser le cmdlet PowerShell "Get-EventLog". Bien que ce cmdlet soit très pratique, il ne permet pas d'accéder à tous les journaux, donc sachez qu'il existe aussi un second cmdlet prévu pour consulter les journaux : "Get-WinEvent".

Voici la commande à utiliser pour récupérer les logs de notre journal :

Get-EventLog -LogName "PowerShell-Demo"

Pour approfondir l'utilisation de ces cmdlets, vous pouvez consulter ces pages :

IV. Utiliser la classe EventLog avec PowerShell

Pour aller plus loin dans l'écriture d'événements dans un journal Windows, il convient d'exploiter la classe EventLog directement depuis PowerShell. Celle-ci va nous permettre d'ajouter des données mieux structurées dans notre événement, notamment dans la section "EventData" visible à partir de la vue XML. C'est utile pour stocker plusieurs informations tout en permettant de récupérer de façon indépendante chaque information.

Voici un exemple :

PowerShell - EventLog - EventData

Nous avons mis en pratique cette méthode dans ce tutoriel :

Ceci complexifie l'inscription d'un nouvel événement, car nous devons créer nos propres objets et nous passer de l'utilisation de Write-EventLog. Un premier objet "System.Diagnostics.EventInstance" permettra d'indiquer le numéro d'ID et le type d'événements, tandis qu'un second objet "System.Diagnostics.EventLog" permettra de préciser les données de l'événement.

Néanmoins, pour que l'utilisation reste simple, nous vous proposons d'utiliser cette fonction :

function Write-EventLogV2 {
    <#
    .SYNOPSIS
        Crée un évènement dans l'observateur d'évènement
    .DESCRIPTION
        La fonction utilise la CmdLet WriteEvent pour créer un évènement à partir des paramètres d'entrée. 
    .PARAMETER dataUser
        Nom utilisateur qui sera inscrit dans le contenu de l'évènement à créer
    .PARAMETER dataDescription
        Contenu de la description qui sera inscrite dans le contenu de l'évènement à créer
    .PARAMETER ID
        Event ID de l'évènement à créer
    .PARAMETER evtLog
        Journal de l'évènement à créer
    .PARAMETER evtSource
        Source de l'évènement à créer
    .EXAMPLE
        New-EventLog -dataUser "John" -dataDescription "new description"
    .OUTPUTS
        None
    #>
    param(
          [Parameter(Mandatory=$true)]$dataUser,
          $dataDescription="",
          $ID=10000,
          $evtLog="PowerShell-Demo",
          $evtSource="Script-2"
          )

    # Charge la source d'événement dans le journal si elle n'est pas déjà chargée.
    # Cette opération échouera si la source d'événement est déjà affectée à un autre journal.
    if ([System.Diagnostics.EventLog]::SourceExists($evtSource) -eq $false) {
        [System.Diagnostics.EventLog]::CreateEventSource($evtSource, $evtLog)
    }

    # Construire l'événement et l'enregistrer
    $evtID = New-Object System.Diagnostics.EventInstance($ID,1)
    $evtObject = New-Object System.Diagnostics.EventLog
    $evtObject.Log = $evtLog
    $evtObject.Source = $evtSource
    $evtObject.WriteEvent($evtID, @($dataUser,"Description : $dataDescription"))
  }

En entrée, cette fonction accepte deux messages ($dataUser et $dataDescription - vous pouvez renommer ces paramètres dont le nom a été choisi vis-à-vis du script d'origine), un numéro d'ID (par défaut, ce sera 10000), le nom d'un journal d'événement (par défaut, ce sera "PowerShell-Demo") ainsi qu'une source (par défaut, ce sera "Script-2").

De plus, par défaut, cette fonction génère des événements de type "Information". Si vous souhaitez changer le type d'événement, vous devez ajuster la valeur présente sur cette ligne :

$evtID = New-Object System.Diagnostics.EventInstance($ID,1)

En effet, la première valeur correspond à l'ID souhaité, ici associé à la variable $ID, tandis que la seconde valeur correspond au type d'événement. Le 1 correspond au type "Information".

Ce qui permettra de générer des événements similaires à celui-ci :

Si besoin, vous pouvez ajouter d'autres valeurs dans la seconde partie de "$evtObject.WriteEvent" pour avoir des lignes "<Data>" supplémentaires.

V. Conclusion

En suivant ce tutoriel, vous devriez être en mesure de créer vos propres événements personnalisés dans les journaux Windows, que ce soit dans un journal existant ou dans votre propre journal à l'aide de PowerShell ! Libre à vous d'utiliser ces cmdlets ou cette fonction dans vos scripts, et de les adapter à vos besoins ! En tout cas, ceci ouvre des possibilités très intéressantes !

author avatar
Florian BURNEL Co-founder of IT-Connect
Ingénieur système et réseau, cofondateur d'IT-Connect et Microsoft MVP "Cloud and Datacenter Management". Je souhaite partager mon expérience et mes découvertes au travers de mes articles. Généraliste avec une attirance particulière pour les solutions Microsoft et le scripting. Bonne lecture.
Partagez cet article Partager sur Twitter Partager sur Facebook Partager sur Linkedin Envoyer par mail

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.