PowerShell FileSystemWatcher : Überwachung von Verzeichnissen oder gar Dateien

Für die Überwachung von Verzeichnissen oder Dateien bietet die Klasse . Mit dieser Klasse ist es möglich auf bestimmte Events zu reagieren, die im überwachten Dateiverzeichnis auftreten. Man findet diese Klasse im Namespace System.IO des .Net-Frameworks.

Ich habe hier mal ein Beispiel für die Verwendung dieser Klasse erstellt. Es geht mir hierbei darum, ein Verzeichnis zu überwachen und dabei insbesondere eine bestimmte Datei.

Wenn diese Datei umbenannt, gelöscht, neu erstellt wird oder sich der Inhalt ändert, dann soll jeweils eine entsprechende Ausgabe erfolgen. Dazu wird eine globale Funktion aufgerufen, an die auch die entsprechende Meldung übergeben wird.

Prüfmechanismen, die bspw. auf Vorhandensein der Filterdatei prüfen etc., wurden hier aus Übersichtsgründen weggelassen. Die Datei muss also beim Start des Scripts schon vorhanden sein.

# Vor dem Start werden alte, registrierte Events geschlossen

Unregister-Event -SourceIdentifier *

# Initialisierung der Variablen

# Gesamtpfad bis zur Datei | resolve-path löst Platzhalterzeichen im Pfad auf
# Die Variable $Path muss global definiert werden, weil der EventWatcher
# in einem eigenen Bereich läuft und sie sonst nicht finden würde.
# Die globale Definition gilt für die Ausführung als Script-Datei *.ps1 ..
# ..sonst geht’s auch ohne

$global:Path = Resolve-Path(„D:\error.log„)

# split-path gibt den übergeorneten Container des Pfads zurück : also Pfad, ohne Dateinamen

$Folder = (Split-Path $Path)

# Filter für die Überwachung…
# ..auch Wildcards (z.B. *.log | er*.*g | erro*.l*g | usw. ) gehen…
# hier: Datei, die oben im Pfad/$Path angegeben ist
# Split-Path $Path –Leaf -> liefert nur Dateinamen aus Variable $Path

$Filter = Split-Path $Path -Leaf  

# FileSystemWatcher aufbauen und Überwachung starten

$FSW = new-object system.io.filesystemwatcher # FileSystemWatcher erstellen
$FSW.
P
ath = $Folder # zu überwachendes Verzeichnis übergeben
$FSW
.IncludeSubdirectories = $False # Unterverzeichnisse einschließen? : NEIN!
$FSW
.Filter = $Filter # Filter für die Überwachung… auch Wildcards gehen…

# Die Funktion out_Text() muss global definiert werden, weil der EventWatcher
# in einem eigenen Bereich läuft und sie sonst nicht finden würde.
# Die globale Definition gilt für die Ausführung als Script-Datei *.ps1

function global:out_Text($txt) { Write-Host („{0}“ -f $txt) }

$OnCreate = { 
  $text = „Ereignis: [{0}] in {1} : {2:d}“ –f    $eventArgs.ChangeType, 
    $eventArgs.FullPath, $Event.TimeGenerated 
  out_Text
($text) # Funktion out_Text aufrufen und Ausgabetext übergeben
}

$OnChange = {
  $text = „Ereignis: [{0}] in {1} : {2:d}“ –f    $eventArgs.ChangeType,
    $eventArgs.FullPath, $Event.TimeGenerated
  out_Text ($text) # Funktion out_Text aufrufen und Ausgabetext übergeben
}

$OnRename = {
  $text = „Ereignis: [{0}] in {1} : {2:d}“ –f    $eventArgs.ChangeType,
    $eventArgs.FullPath, $Event.TimeGenerated
  out_Text ($text) # Funktion out_Text aufrufen und Ausgabetext übergeben
}

$OnDelete = {
  $text = „Ereignis: [{0}] in {1} : {2:d}“ –f    $eventArgs.ChangeType,
    $eventArgs.FullPath, $Event.TimeGenerated
  out_Text ($text) # Funktion out_Text aufrufen und Ausgabetext übergeben
}

# abonniert das entsprechende Ereignis für DATEI ERSTELLT, GEÄNDERT, UMBENANNT, GELÖSCHT
# das „" ist ein Zeilenumbruch im Script

Register-ObjectEvent -InputObject $FSW 
-EventName Created -SourceIdentifier FileCreated -Action $OnCreate | Out-Null
Register-ObjectEvent -InputObject $FSW 
-EventName Changed -SourceIdentifier FileChanged -Action $OnChange | Out-Null
Register-ObjectEvent -InputObject $FSW 

-EventName Renamed -SourceIdentifier FileRenamed -Action $OnRename | Out-Null
Register-ObjectEvent -InputObject $FSW `
-EventName Deleted -SourceIdentifier FileDeleted -Action $OnDelete | Out-Null

# abonnierte Ereignisse laufen im Hintergrund und können per Befehl
# Unregister-Event -SourceIdentifier * wieder beendet werden (siehe ganz oben)

 

Wenn Sie das Script ausführen, werden die verschiedenen Events überwacht und auf jedes einzelne davon wird entsprechend reagiert. Wie man sehen kann, tritt beim zweiten Befehl (dir >> error.log) ein Ereignis Created und ein Ereignis Changed auf. Dies liegt daran, dass die Log-Datei vorher per del-Befehl gelöscht wurde und zum aktuellen Zeitpunkt also nicht mehr existierte. Daher wird sie erst neu erstellt (Created) und dann geändert (Changed).

Falls Sie vorhaben einen geplanten Task (Windows-Aufgabenplanung) einzurichten, der dieses Script auch nach jedem Neustart wieder aktiviert, dann nutzen Sie die folgende Zeile:
%windir%\system32\windowspowershell\v1.0\powershell.exe noexit File D:\FileSysWatch.ps1

Der Parameter –noexit verhindert, dass das Programm nach ausgeführten Startbefehlen beendet wird.

 

3 Gedanken zu „PowerShell FileSystemWatcher : Überwachung von Verzeichnissen oder gar Dateien

  1. Guten Tag,

    das Skript läuft soweit ausgezeichnet.
    Wenn ich jedoch eine Datei direkt im Editor bearbeite und speichere bekomme ich zwei mal den Change Aufruf. Wissen Sie woran das liegen kann?

  2. Schönen guten Tag!
    Ich habe das Skript von Ihnen gestet und danke Ihnen für die Anleitung!
    Leider habe ich ein Problem: Wenn ich das Skript über einen Batchjob auslöse läuft es nicht. Starte ich es direkt aus der Powershell ist es kein Problem. Haben Sie eine Idee woran das liegen kann?

    Vielen Dank vorab für Ihre Rückmeldung!
    Werner Landsperger

    • Hallo Werner,

      ich hoffe ich verstehe Deine Frage richtig und du willst das Script als geplante Aufgabe regelmäßig starten. Bitte versuche an dieser Stelle mal nur den Parameter -command wie hier beschrieben: http://www.dacomsys.de/powershell-script-als-geplante-aufgabe/

      Es gibt je nach Windows Version manchmal Unterschiede bei der Ausführung eines PowerShell Scriptes. Achte bitte auch auf die Execution Policy der PowerShell (Get-Help Set-ExecutionPolicy).

Kommentar verfassen

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.