Dans cet article, je souhaite parler du FileSystemWatcher, une fonctionnalité .NET bien utile
qui consiste à écouter les changements du système de fichier windows.
D’une manière générale, cette fonctionnalité permet d’être averti quand un changement s’opère, et d’effectuer des actions quand ce changement se produit.
L’objet FileSystemWatcher nous permet d’écouter les évènements suivants du système de fichier :
- Changed
- Renamed
- Created
- Deleted
Coté implémentation, nous devrons suivre la séquence suivante dans nos scripts:
- Créer et configurer un objet de type filesystemwatcher
- L’enregistrer pour écouter un évènement particulier
L’objet FileSystemWatcher
#Nous commençons par créer l'objet dans une variable : [IO.FileSystemWatcher]$FileSystemWatcher = New-Object System.IO.FileSystemWatcher #Nous pouvons observer ses propriétés : $FileSystemWatcher

Ci-joint la liste des principales propriétés de l’objet FileSystemWatcher et leurs descriptions respectives. Documentation complète
Path | Récupère ou modifie le chemin du dossier à écouter |
EnableRaisingEvents | Active ou désactive le composant |
Filter | Récupère ou modifie le filtre d’écoute. Permet de déterminer les fichier et dossier à écouter. La valeur par défaut est « *.* |
IncludeSubdirectories | Active ou désactive le fait d’écouter les sous-dossiers |
InternalBufferSize | Récupère ou modifie la taille du tampon interne. La valeur par defaut est 8K, doit être un multiple de 4K pour les systèmes Intel. Ne peut être inférieur à 4K |
NotifyFilter | Récupère ou modifie le type d’évènement à écouter |
La propriété NotifyFilter
Habituellement, vous aurez à modifier le NotifyFilter, Filter, IncludeSubdirectories and Path.
Pour la propriété NotifyFilter, nous passerons par un enumérateur de type NotifyFilters. La valeur par défaut est LastWrite, FileName and DirectoryName.
Vous pouvez accéder aux valeur possibles en appellant cet énnumérateur et appuyer sur CTRL + ESPACE pour faire apparaître l’intellisense :
[System.IO.NotifyFilters]:: # CTRL + ESPACE

Vous trouverez en dessous les valeurs que nous pouvons suivre et leurs déscriptions respectives:
Attributes | Les attributs du fichier ou dossier |
CreationTime | La date à laquelle le fichier ou dossier à été créé |
DirectoryName | Le nom du dossier |
FileName | Le nom du fichier |
LastAccess | La date à laquelle le fichier ou dossier à été ouvert en dernier |
LastWrite | La date à laquelle le fichier ou dossier à été modifié en dernier |
Security | Les attributs de sécurité du fichier ou dossier |
Size | La taille du fichier ou dossier |
Gardez en tête que vous pouvez écouter toute ces valeur pour un changement.
Les évènements renamed, created and deleted ne seront déclenchés que par les valeurs DirectoryName and FileName
Maintenant que nous avons fait le tour de ce concept, je vous propose de passer à des exemples complets…
Ecouter les modifications de tout les fichiers de scripts dans un dossier
#Créer un hashtable pour les propriétés de notre objet FilssystemWatcher $param = @{ Path = "C:\Scripts"; Filter = "*.ps1"; IncludeSubDirectories = $False; NotifyFilter = [System.IO.NotifyFilters]::FileName,[System.IO.NotifyFilters]::LastWrite } #Créer le FileSystemWatcher en lui passant nos propriétés [IO.FileSystemWatcher]$scriptAccessWatcher = New-Object IO.FileSystemWatcher -property $param #L'enregistrer pour écouter l'evenement "Changed" #$scriptAccessWatcher | gm |?{$_.MemberType -like 'Event'} #to see the available event names Register-ObjectEvent $scriptAccessWatcher Changed -Action { #Nous pouvons accéder aux propriétés de l'évènement à travers la variale $Event #Vous pouvez décomenter la ligne suivante pour en faire une variable globale #et y accéder dans la session en appellant cette variable #$Global:MyEventRaised = $Event $name = $Event.SourceEventArgs.Name $timeStamp = $Event.TimeGenerated $changeType = $Event.SourceEventArgs.ChangeType Write-Host "$name has been $changeType at $timeStamp" }

Ecouter les création de dossiers dans un dossier (et sous-dossiers)
#Créer un hashtable pour les propriétés de notre objet FilssystemWatcher $param = @{ Path = "C:\Scripts"; Filter = "*.*"; IncludeSubDirectories = $True; NotifyFilter = [System.IO.NotifyFilters]::DirectoryName } #Créer le FileSystemWatcher en lui passant nos propriétés [IO.FileSystemWatcher]$scriptAccessWatcher = New-Object IO.FileSystemWatcher -property $param #L'enregistrer pour écouter l'evenement "Created" #$scriptAccessWatcher | gm |?{$_.MemberType -like 'Event'} #to see the available event names Register-ObjectEvent $scriptAccessWatcher Changed -Action { #Nous pouvons accéder aux propriétés de l'évènement à travers la variale $Event #Vous pouvez décomenter la ligne suivante pour en faire une variable globale #et y accéder dans la session en appellant cette variable #$Global:MyEventRaised = $Event $name = $Event.SourceEventArgs.Name $timeStamp = $Event.TimeGenerated $changeType = $Event.SourceEventArgs.ChangeType Write-Host "$name has been $changeType at $timeStamp" }

Vous trouverez ci-dessous un moyen de vérifier sur un évènement existe déjà dans votre session
#Vous pouvez filtrer voter recherche en utilisant le SourceObject #qui est notre FileSystemWatcher et comparer les valeur $objEvents = Get-EventSubscriber | ?{($_.SourceObject.Path -eq $param.Path) -and ($_.SourceObject.Filter -eq $param.Filter) -and ($_.EventName -eq 'Created')} #Si necessaire, nous pouvons supprimer cet évènement et ne plus être notifié $objEvents | Unregister-Event
J’utilise cette fonctionnalité .NET pour charger dynamiquement des fichiers de configuration. J’espère que ça vous donnera des idées 😉
A bientôt sur le blog !