sugram
Goto Top

Überwachung von Dateien

Hallo

Ich habe hier ein Powershell Script, daß mir bei Veränderungen an bestimmten Dateien eine Email sendet.
Soweit klappt das mittlerweile auch.
Allerdings, wenn ich die Powershell starte, bekomme ich von jeder Datei die in den Verzeichnissen gefunden werden eine Benachrichtigung, daß sie geändert worden sind.
Also wenn da 3 Dateien vorhanden sind, bekomme ich 3 Emails.
Ich lösche die Mails und verändere dann eine Datei und dann erhalte ich auch nur von dieser geänderten Datei die Benachrichtigung.
Ich verstehe nur nicht, weshalb ich beim starten der Powershell von allen Dateien eine Benachrichtigung erhalte.
Hat da jemand ne Idee?

Hier mal der Code

$computers = "1234567"   # Liste der Computernamen  

$folderToWatch = "c\test\TEST"  

$filter = "*.cfg"  

$intervalSeconds = 2   # Intervall in Sekunden (1 Minute)

$emailFrom = "noreplay@xyz.com"  
$emailTo = "user@xyz.com"  
$emailSubject = "CFG Datei geändert!!!"  
$emailSMTPServer = "smtp.com"  

$lastWriteTimeList = @{}   

while ($true) {
    foreach ($computer in $computers) {
        $files = Get-ChildItem -Path "\\$computer\$($folderToWatch.TrimStart('C:\'))" -Filter $filter -Recurse  
        foreach ($file in $files) {
            if ($lastWriteTimeList[$file.FullName] -ne $file.LastWriteTime) {
                $lastWriteTimeList[$file.FullName] = $file.LastWriteTime
                $body = "Die folgende Datei wurde geändert: $($file.FullName)"  
                Send-MailMessage -From $emailFrom -To $emailTo -Subject $emailSubject -Body $body -SmtpServer $emailSMTPServer -encoding ([System.Text.Encoding]::UTF8)
            }
        }
    }
    Start-Sleep -Seconds $intervalSeconds
}

Content-Key: 5976903601

Url: https://administrator.de/contentid/5976903601

Printed on: April 27, 2024 at 09:04 o'clock

Member: StefanKittel
StefanKittel Feb 14, 2023 at 10:43:15 (UTC)
Goto Top
Moin,

beim 1. Aufruf ist lastWriteTimeList doch leer.
Du könntest diese Liste z.B. in der Registry oder einer XML-Datei speichern.
Oder beim 1. Durchlauf keine Warnung ausgeben.
Oder das Archiv-Attribute (A) verwenden und danach löschen.

Stefan
Member: sugram
sugram Feb 14, 2023 at 10:59:16 (UTC)
Goto Top
Ok, das mit dem lastWriteTimeList, daß die am Anfang leer ist, hatte ich nicht bedacht.

Zitat von @StefanKittel:


Oder beim 1. Durchlauf keine Warnung ausgeben.

Wie kann ich das denn machen?
Steh da glaube ich auf dem Schlauch.
Member: emeriks
Solution emeriks Feb 14, 2023 at 13:23:52 (UTC)
Goto Top
Hi,
Du legst z.B. eine Variable $LoopCounter fest
[int]$LoopCounter = 0
Dann 1. Zeile nach dem "While"
$LoopCounter += 1
Und das "Send-MailMessage" kapselst Du in eine IF
IF($LoopCounter -gt 1) {
  Send-MailMessage ...
}

E.
Member: emeriks
Solution emeriks Feb 14, 2023 at 13:26:31 (UTC)
Goto Top
Oder ohne Counter:

Vor dem 1. "While" eine abgespeckte Variante davon, zum Füllen der Tabelle :

foreach ($computer in $computers) {
  $files = Get-ChildItem -Path "\\$computer\$($folderToWatch.TrimStart('C:\'))" -Filter $filter -Recurse  
  foreach ($file in $files) {
     $lastWriteTimeList[$file.FullName] = $file.LastWriteTime
  }
}
Member: Crusher79
Crusher79 Feb 14, 2023 at 15:30:11 (UTC)
Goto Top
https://powershell.one/tricks/filesystem/filesystemwatcher

Für deinen Fall müsste man folgendes nur erweitern:

$ChangeTypes = [System.IO.WatcherChangeTypes]::Created, [System.IO.WatcherChangeTypes]::Deleted

$ChangeTypes = [System.IO.WatcherChangeTypes]::Created, [System.IO.WatcherChangeTypes]::Deleted, [System.IO.WatcherChangeTypes]::Changed

Momentan gibt es dann eine Ausgabe an der Konsole. Kann aber alles sein.

Schau dir mal das Script an...
Member: sugram
sugram Feb 15, 2023 updated at 04:25:35 (UTC)
Goto Top
Vielen Dank euch allen!


Zitat von @emeriks:

Oder ohne Counter:

Vor dem 1. "While" eine abgespeckte Variante davon, zum Füllen der Tabelle :

foreach ($computer in $computers) {
  $files = Get-ChildItem -Path "\\$computer\$($folderToWatch.TrimStart('C:\'))" -Filter $filter -Recurse  
  foreach ($file in $files) {
     $lastWriteTimeList[$file.FullName] = $file.LastWriteTime
  }
}

Das funktioniert einwandfrei!

Den Vorschlag von Crusher79 schaue ich mir dann auch mal genauer an.