Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit

Dateiüberwachung -Hinzufügen oder Entfernen- in einem Verzeichnis per VBScript

Anleitung Entwicklung VB for Applications

Mitglied: Bitsqueezer

Bitsqueezer (Level 1) - Jetzt verbinden

04.11.2007, aktualisiert 18.10.2012, 28213 Aufrufe, 14 Kommentare

Wie man in einem Verzeichnis das Auftreten oder Löschen von Dateien per VBScript überwachen kann mit Eintrag in das Anwender-Eventlog von Windows. Verwendbar für zum Beispiel MOM/SCOM, "Geplante Tasks" oder mit anderen Schedulern.

Zweck

Sinn dieses Scriptes soll es sein, ein Verzeichnis zu überwachen, um festzustellen, ob ein bestimmter Dateityp auftritt und/oder gelöscht wurde. Das kann man zum Beispiel verwenden, um auf die Ausgabe von Error-Logdateien einer Anwendung schnell reagieren zu können oder um auf einem Fileserver zu prüfen, ob etwa eine MP3-Datei von einem User abgelegt wurde.

Um ein Verzeichnis zu überwachen, gibt es sicherlich einige Methoden, von der in NTFS eingebetteten "Überwachung"-Einstellung bis hin zu Tools oder ganzen Softwaresuiten.
Problem ist, wenn man auf Windows-Bordmittel angewiesen und kein teures Zusatztool kaufen möchte, dann hilft nur selbst scripten. Nebeneffekt ist, daß man das folgende Script auch in allen Softwareprodukten einsetzen kann, die das Ausführen von VBScript unterstützen oder die wenigstens Eventlogs auslesen können. Alternativ kann man das Schreiben der Eventlogs natürlich auch in eine Bildschirmausgabe oder in eine Dateiausgabe umlenken, um das Ergebnis auszulesen.

Erster Versuch

Da es unter der Kommandozeilenebene ein nettes Progrämmchen namens "fc" gibt (FileCompare), mit dem man zwei Dateien auf Unterschiede überprüfen kann, war mein erster Versuch das folgende kleine DOS-Batchprogramm:

01.
@echo off 
02.
if not exist Switch1.txt (if not exist Switch0.txt (echo 1 >Switch0.txt)) 
03.
if exist Switch0.txt (set DirFile=Content0.txt) else (set DirFile=Content1.txt) 
04.
dir Logs /b /o /a-d err*.log 1>%DirFile% 2>Null 
05.
if exist Content0.txt (if exist Content1.txt (fc Content0.txt Content1.txt >Unterschied.log)) 
06.
if exist Switch1.txt (ren Switch1.txt Switch0.txt) else (ren Switch0.txt Switch1.txt)
Das funktioniert auch, hat nur den Nachteil, daß die Ausgabe von fc wieder so kompliziert ist, daß man sie für eine programmgesteuerte Abfrage wieder regelrecht dekodieren muß, was aufwändiger wäre als das eigentliche Ziel.

Lösung in VBScript

Daher hier nun eine Lösung, wie man das ganze in VBScript durchführen kann. Der Vorteil von VBScript ist, daß es im Gegensatz zur DOS-Batchdatei einen Haufen mehr Möglichkeiten hat, so etwa das Eintragen von Events in das Anwendungs-Eventlog von Windows.

Hier kann man alternativ natürlich auch andere Wege gehen, um die Benachrichtigung für das Überwachungsziel auszulösen, ganz nach eigenem Geschmack. Das Eventlog hat den Vorteil, daß es in Softwaresuiten wie MOM/SCOM oder ähnlichen automatisch überwacht werden kann. SCOM könnte beispielsweise eine automatische Löschung von MP3-Dateien durchführen, wenn es sie auf dem Fileserver im überwachten Verzeichnis findet, außerdem kann SCOM selbst der Scheduler zum Ausführen des Scriptes sein.

Alternativ kann man der Scheduler auch jedes andere dafür geeignete Programm sein, also zum Beispiel auch der zu Windows gehörende Taskplaner. Bei der Erstellung unter "Geplante Tasks" kann man zwar nur tageweise Ausführung eingeben, wenn der Task aber erstellt ist, kann man in seinen Eigenschaften bis herunter zu minütlicher Ausführung gehen.

Man sollte allerdings bei sehr großen Verzeichnissen oder langsamen Rechnern die Ausführung nicht zu klein einstellen und auch an die zusätzliche CPU-Belastung auf etwa einem Fileserver denken, wenn das Script zu oft ausgeführt wird. Je nach Größe des überwachten Ordners könnte es auch dazu führen, daß das Script ausgeführt wird, während eine frühere Instanz des Scriptes noch ausgeführt wird, was dann zu einem Durcheinander und Fehlmeldungen führen könnte.
Es ist daher sinnvoll, sich vorher Gedanken darüber zu machen, wie oft man wirklich eine Überwachung eines Ordners benötigt, wie oft man mit dem Auftreten/Löschen der überwachten Dateitypen rechnet und wie schnell man über diese Information verfügen möchte.

Während der Ausführung des Scriptes wird ein "Dir"-Kommando auf Kommandozeilenebene ausgeführt, was zur Folge hat, das ganz kurz ein CMD-Fenster aufblinkt. Wer das störend findet, kann im Internet nach dem kleinen Ersatz "CMDOW" suchen, der ein CMD ohne Fenster ausführt. Hier ging es mir aber darum, wirklich nur Windows-Bordmittel zu verwenden, da man "im Einsatz" in der Regel keine zusätzlichen Tools zur Verfügung hat oder Freeware nicht eingesetzt werden darf.

Weitere Detailerläuterungen zum Script finden sich im Script in den Kommentaren, ebenso eine Erläuterung über die Parameter, die man per Konstanten zu Beginn des Scriptes anpassen kann.

Viel Spaß mit dem Tool und mit dem Experimentieren mit eigenen Erweiterungen. Wer zusätzliche Ideen hat oder Anmerkungen, wie man etwas noch leichter hinbekommen kann, ist herzlich eingeladen, Kommentare zu schreiben. Nothing is perfect.

Christian

PS.: Mit Hilfe des Tutorials, was ich vorhin hier gefunden habe, könnte man das ganze dahingehend erweitern, daß automatisch eine EMail geschickt wird, wenn das Script einen Eintrag in das Eventlog schreibt:

http://www.administrator.de/Eventlog_Mailer.html

Das Script


01.
' Dateiüberwachung in einem Verzeichnis 
02.
' ************************************* 
03.
' V1.0  02.Nov.2007 
04.
' Letzte Änderung: 02.Nov.2007 
05.
06.
' Autor: Christian Coppes 
07.
' kann in SCOM oder anderen Schedulern (z.B. "Geplante Tasks") zur Überwachung von Verzeichnissen eingesetzt werden 
08.
09.
' Die Datei muß mit irgendeiner Art von Scheduler in regelmäßigen Abständen aufgerufen werden. 
10.
' Je nach Größe des Zielverzeichnisses sollte man die Zeit nicht zu kurz wählen, damit das Skript nicht 
11.
' läuft, während eine alte Instanz noch nicht fertig ist. 
12.
' Es empfiehlt sich, einen Wert von ca. 1 Minute nicht zu unterschreiten. 
13.
' Mit den Konstanten unten kann man die Parameter an eigene Bedürfnisse anpassen. 
14.
15.
' Funktionsweise: Per CMD-"dir"-Befehl wird der Inhalt des gewünschten Verzeichnisses 
16.
' unter Verwendung von FILEMASK abwechselnd in die Datei DIRFILE0 und DIRFILE1 eingetragen. 
17.
18.
' Zur Feststellung, welche Datei zuletzt verwendet wurde, dient die Datei SWITCHFILE0, die dann 
19.
' abwechselnd in SWITCHFILE1 umbenannt wird. 
20.
21.
' Es wird daraufhin festgestellt, welche die neuere DIRFILE ist, um die Änderung gegenüber der älteren 
22.
' zu protokollieren. 
23.
24.
' Die beiden DIRFILEs werden in jeweils ein Array eingelesen, die ältere Datei immer in "Zeile0", 
25.
' die neuere immer in "Zeile1". 
26.
27.
' Mit Hilfe des VBScript-Filter-Befehls wird dann Zeile für Zeile verglichen, welche Zeile in der älteren 
28.
' Datei nicht vorhanden ist und diese in das Array "Hinzu1" eingefügt. Umgekehrt wird dann der Vergleich 
29.
' durchgeführt, um Zeilen, die in der neueren Datei nicht mehr enthalten sind, in "Weg1" zu schreiben. 
30.
31.
' Zuletzt wird für beide Gruppen je ein Event im Application Event Log angelegt. Über die Konstanten kann 
32.
' man festlegen, ob auch die entfernten Dateien protokolliert werden und welche Art von Event dabei 
33.
' generiert werden soll. 
34.
35.
' Darüber hinaus wird nur ein Event generiert für alle hinzugekommenen und ein Event für alle gelöschten 
36.
' Dateien, um die Anzahl der Events nicht zu groß werden zu lassen. 
37.
38.
' Die Events können dann beispielsweise mit SCOM (Microsoft System Center Operations Manager) ausgewertet werden. 
39.
40.
' Folgende DOS-Batchdatei prüft ebenfalls auf Dateiunterschiede. 
41.
' Dies ist die VBS-Version, die ein wenig komfortabler ist. 
42.
43.
'@echo off 
44.
'if not exist Switch1.txt (if not exist Switch0.txt (echo 1 >Switch0.txt)) 
45.
'if exist Switch0.txt (set DirFile=Content0.txt) else (set DirFile=Content1.txt) 
46.
'dir Logs /b /o /a-d err*.log 1>%DirFile% 2>Null 
47.
'if exist Content0.txt (if exist Content1.txt (fc Content0.txt Content1.txt >Unterschied.log)) 
48.
'if exist Switch1.txt (ren Switch1.txt Switch0.txt) else (ren Switch0.txt Switch1.txt) 
49.
'echo On 
50.
 
51.
' Verzeichnis (absolut oder relativ zum Skriptpfad), in dem die Dateien protokolliert werden sollen 
52.
Const LOGDIR = "Z:\Public\Compare\Logs" 
53.
' Dateien, die gesucht werden sollen 
54.
Const FILEMASK = "err*.log" 
55.
' Art der verwendeten Logbucheinträge, 0 = Success, 1 = Error, 2 = Warning, 4 = Information 
56.
Const NEWEVENT = 1 
57.
Const DELEVENT = 2 
58.
 
59.
' Diese temporären Dateien werden für den Vergleich benötigt. 
60.
' Das Script muß in diesen Verzeichnissen Schreibrechte haben. 
61.
Const DIRFILE0 = "C:\Windows\Debug\Content0.txt" 
62.
Const DIRFILE1 = "C:\Windows\Debug\Content1.txt" 
63.
Const SWITCHFILE0 = "C:\Windows\Debug\Switch0.txt" 
64.
Const SWITCHFILE1 = "C:\Windows\Debug\Switch1.txt" 
65.
 
66.
' NewDel = 1: Alle Unterschiede protokollieren 
67.
' NewDel = 0: Nur neu hinzugekommene Dateien protokollieren 
68.
Const NewDel = 1 
69.
 
70.
Dim i, j, EventStr, AnzHinzu, AnzWeg 
71.
Dim Datei,SwitchFile, DirFile 
72.
Dim objFSO, objShell 
73.
 
74.
Dim Zeile0(), Zeile1() 
75.
Dim Hinzu, Hinzu1() 
76.
Dim Weg, Weg1() 
77.
Dim DummyFile 
78.
 
79.
Set objFSO   = CreateObject("Scripting.FileSystemObject") 
80.
Set objShell = CreateObject("WScript.Shell") 
81.
82.
' Wurde schon eine Switchdatei erstellt? 
83.
If ((Not objFSO.FileExists(SWITCHFILE0))  And _ 
84.
    (Not objFSO.FileExists(SWITCHFILE1))) Then 
85.
   ' Switch-Datei erzeugen 
86.
   Set SwitchFile=objFSO.OpenTextFile(SWITCHFILE0,2,true) 
87.
   SwitchFile.WriteLine "1"   ' Dummyinhalt 
88.
   SwitchFile.Close 
89.
End If 
90.
 
91.
' Schalterdatei prüfen und den Dateinamen für das Inhaltsverzeichnis 
92.
' entsprechend einstellen (abwechselndes Schreiben) 
93.
If objFSO.FileExists(SWITCHFILE0) Then 
94.
   DirFile=DIRFILE0 
95.
Else 
96.
   DirFile=DIRFILE1 
97.
End If 
98.
 
99.
' Alle Err-Dateien aus dem Ordner sortiert in eine der beiden Content- 
100.
' Dateien schreiben 
101.
objShell.Run("%windir%\system32\cmd.exe /c dir "+ LOGDIR +" /b /o /a-d " + FILEMASK + " 1>"+DirFile+" 2>Null") 
102.
 
103.
' Am Ende der Ausführung Schalter für den nächsten Durchlauf "umlegen" 
104.
If objFSO.FileExists(SWITCHFILE0) Then 
105.
   'Datei umbenennen 
106.
   objFSO.MoveFile SWITCHFILE0 , SWITCHFILE1 
107.
Else 
108.
   objFSO.MoveFile SWITCHFILE1 , SWITCHFILE0 
109.
End If 
110.
 
111.
' ***************************************************** 
112.
' Dateivergleich zwischen Content0.txt und Content1.txt 
113.
' ***************************************************** 
114.
 
115.
' In "Zeile0" immer die ältere Datei einlesen und 
116.
' in "Zeile1" immer die neuere 
117.
If DirFile = DIRFILE0 Then 
118.
   DirFileAlt = DIRFILE1 
119.
   DirFileNeu = DIRFILE0 
120.
Else 
121.
   DirFileAlt = DIRFILE0 
122.
   DirFileNeu = DIRFILE1 
123.
End If 
124.
 
125.
'DIRFILE0 zeilenweise lesen 
126.
Set DummyFile=objFSO.OpenTextFile(DirFileAlt,1,true) 
127.
i=0 
128.
Do until DummyFile.AtEndOfStream 
129.
  ReDim Preserve Zeile0(i) 
130.
  Zeile0(i)=DummyFile.ReadLine 
131.
  i=i+1 
132.
Loop 
133.
DummyFile.Close 
134.
Set DummyFile=Nothing 
135.
 
136.
'DIRFILE1 zeilenweise lesen 
137.
Set DummyFile=objFSO.OpenTextFile(DirFileNeu,1,true) 
138.
i=0 
139.
Do until DummyFile.AtEndOfStream 
140.
  ReDim Preserve Zeile1(i) 
141.
  Zeile1(i)=DummyFile.ReadLine 
142.
  i=i+1 
143.
Loop 
144.
DummyFile.Close 
145.
Set DummyFile=Nothing 
146.
 
147.
' Hinzugekommene Dateien in das Array "Hinzu1" schreiben 
148.
AnzHinzu=-1 
149.
For i = 0 To UBound(Zeile1) 
150.
   Hinzu = Filter(Zeile0,Zeile1(i),True) 
151.
   If UBound(Hinzu)=-1 Then 
152.
      AnzHinzu = AnzHinzu + 1 
153.
      ReDim Preserve Hinzu1(AnzHinzu) 
154.
      Hinzu1(AnzHinzu)=Zeile1(i) 
155.
   End If 
156.
Next 
157.
 
158.
' Entfernte Dateien in das Array "Weg1" schreiben 
159.
If NewDel = 1 then 
160.
	AnzWeg=-1 
161.
	For i = 0 To UBound(Zeile0) 
162.
	   Weg = Filter(Zeile1,Zeile0(i),True) 
163.
	   If UBound(Weg)=-1 Then 
164.
	      AnzWeg = AnzWeg + 1 
165.
	      ReDim Preserve Weg1(AnzWeg) 
166.
	      Weg1(AnzWeg)=Zeile0(i) 
167.
	   End If 
168.
	Next 
169.
End If 
170.
 
171.
If AnzHinzu > -1 Then 
172.
   ' Event für hinzugekommene Dateien in das Logbuch schreiben 
173.
   EventStr = "Neu hinzugekommene Dateien vom Typ "+FILEMASK+" :" + vbCrLF 
174.
   EventStr = EventStr + Join(Hinzu1,vbCrLf) 
175.
   objShell.LogEvent NEWEVENT, EventStr 
176.
   'WScript.Echo("EventHinzu: "+EventStr) 
177.
End If 
178.
 
179.
 
180.
If NewDel = 1 Then 
181.
   If AnzWeg > -1 Then 
182.
       EventStr = "Entfernte Dateien vom Typ "+FILEMASK+" :" + vbCrLF 
183.
	   EventStr = EventStr + Join(Weg1,vbCrLf) 
184.
       ' Event für entfernte Dateien in das Logbuch schreiben 
185.
	   objShell.LogEvent DELEVENT, EventStr 
186.
       'WScript.Echo("EventWeg: "+EventStr) 
187.
   End If 
188.
End If
Mitglied: bastla
04.11.2007 um 15:14 Uhr
Hallo Bitqueezer!

Vorweg ein Dankeschön für Deine Mühe und das daraus entstandene Ergebnis - Verwendung für Dein Script gibt es sicherlich.

Anhand einer auf Deinem Code aufbauenden Version 1.0.1 (und aufgrund Deiner Einladung dazu ) möchte ich einige Anmerkungen anbringen:
01.
' Dateiüberwachung in einem Verzeichnis 
02.
' ************************************* 
03.
' V1.0.1  04.Nov.2007 
04.
' Letzte Änderung: 04.Nov.2007 
05.
06.
' Autor: Christian Coppes 
07.
' Kann in SCOM oder anderen Schedulern (z.B. "Geplante Tasks") zur Überwachung von Verzeichnissen eingesetzt werden 
08.
09.
' Die Datei muss mit irgendeiner Art von Scheduler in regelmäßigen Abständen aufgerufen werden. 
10.
' Je nach Größe des Zielverzeichnisses sollte man die Zeit nicht zu kurz wählen, damit das Skript nicht 
11.
' läuft, während eine alte Instanz noch nicht fertig ist. 
12.
' Es empfiehlt sich, einen Wert von ca. 1 Minute nicht zu unterschreiten. 
13.
' Mit den Konstanten unten kann man die Parameter an eigene Bedürfnisse anpassen. 
14.
15.
' Funktionsweise: Per CMD-"dir"-Befehl wird der Inhalt des gewünschten Verzeichnisses unter 
16.
' Verwendung von FILEMASK eingelesen und in DIRFILE für den nächsten Vergleich zwischengespeichert. 
17.
18.
' Die beiden Dateilisten werden in jeweils ein Array eingelesen, die ältere Liste immer in "Zeile0", 
19.
' die neuere immer in "Zeile1". 
20.
21.
' Mit Hilfe des VBScript-Filter-Befehls wird dann Zeile für Zeile verglichen, welche Zeile in der älteren 
22.
' Datei nicht vorhanden ist und diese in den String "Hinzu1" eingefügt. Umgekehrt wird dann der Vergleich 
23.
' durchgeführt, um Zeilen, die in der neueren Datei nicht mehr enthalten sind, in "Weg1" zu schreiben. 
24.
25.
' Zuletzt wird für beide Gruppen je ein Event im Application Event Log angelegt. Über die Konstanten kann 
26.
' man festlegen, ob auch die entfernten Dateien protokolliert werden und welche Art von Event dabei 
27.
' generiert werden soll. 
28.
29.
' Darüber hinaus wird nur ein Event generiert für alle hinzugekommenen und ein Event für alle gelöschten 
30.
' Dateien, um die Anzahl der Events nicht zu groß werden zu lassen. 
31.
32.
' Die Events können dann beispielsweise mit SCOM (Microsoft System Center Operations Manager) ausgewertet werden. 
33.
34.
' Folgende DOS-Batchdatei prüft ebenfalls auf Dateiunterschiede. 
35.
36.
'@echo off 
37.
'set "Logs=Z:\Public\Compare\Logs" 
38.
'set "FileMask=err*.log" 
39.
'set "DFPath=C:\Windows\Debug" 
40.
'if not exist "%DFPath\Switch1.txt" (if not exist "%DFPath%\Switch0.txt" (echo 1 >"%DFPath%\Switch0.txt")) 
41.
'if exist "%DFPath%\Switch0.txt" (set "DirFile=%DFPath%\Content0.txt") else (set "DirFile=%DFPath%\Content1.txt") 
42.
'dir "%Logs%\%FileMask%" /b /o /a-d>"%DirFile%" 2>Null 
43.
'if exist "%DFPath%\Content0.txt" (if exist "%DFPath%\Content1.txt" (fc "%DFPath%\Content0.txt" "%DFPath%\Content1.txt" >"%DFPath%\Unterschied.log")) 
44.
'if exist "%DFPath%\Switch1.txt" (move "%DFPath%\Switch1.txt" "%DFPath%\Switch0.txt") else (move "%DFPath%\Switch0.txt" "%DFPath%\Switch1.txt" 2>nul) 
45.
 
46.
' Dies ist die VBS-Version, die ein wenig komfortabler ist: 
47.
 
48.
' Verzeichnis, in dem die Dateien protokolliert werden sollen 
49.
Const LOGDIR = "Z:\Public\Compare\Logs" 
50.
' Dateien, die gesucht werden sollen 
51.
Const FILEMASK = "err*.log" 
52.
 
53.
' Art der verwendeten Logbucheinträge, 0 = Success, 1 = Error, 2 = Warning, 4 = Information 
54.
Const NEWEVENT = 1 
55.
Const DELEVENT = 2 
56.
 
57.
' Diese temporäre Datei wird für den Vergleich benötigt. Das Script muss im verwendeten Verzeichnis Schreibrechte haben. 
58.
Const DIRFILE = "C:\Windows\Debug\Content.txt" 
59.
 
60.
' NewDel = 1: Alle Unterschiede protokollieren 
61.
' NewDel = 0: Nur neu hinzugekommene Dateien protokollieren 
62.
Const NewDel = 1 
63.
 
64.
Set objFSO   = CreateObject("Scripting.FileSystemObject") 
65.
Set objShell = CreateObject("WScript.Shell") 
66.
 
67.
'Alte Liste aus DIRFILE in Array Zeile0() einlesen 
68.
If objFSO.FileExists(DIRFILE) Then 'DIRFILE vorhanden 
69.
	Set objDirFile = objFSO.OpenTextFile(DIRFILE, 1) 
70.
	If Not objDirFile.AtEndOfStream Then 'DIRFILE nicht leer 
71.
		strZeile0 = objDirFile.ReadAll 
72.
		Zeile0 = Split(strZeile0, vbCrLF) 
73.
	Else 
74.
		Zeile0 = Array("") 
75.
	End If 'DIRFILE nicht leer 
76.
Else 
77.
	Zeile0 = Array("") 
78.
End If 'DIRFILE vorhanden 
79.
 
80.
' Alle Err-Dateien aus dem Ordner sortiert in das Array Zeile1() einlesen 
81.
strCMD = "%windir%\system32\cmd.exe /c dir " & LOGDIR & " /b /o /a-d " & FILEMASK & " 2>nul" 
82.
strZeile1 = objShell.Exec(strCMD).StdOut.ReadAll 
83.
Zeile1 = Split(strZeile1, vbCrLF) 
84.
 
85.
' Am Ende der Ausführung aktuelle Dateiliste in DIRFILE speichern 
86.
objFSO.OpenTextFile(DIRFILE, 2, True).Write strZeile1 
87.
 
88.
' ************************************************************************* 
89.
' Dateivergleich zwischen Content.txt (Zeile0) und aktueller Liste (Zeile1) 
90.
' ************************************************************************* 
91.
 
92.
If LCase(Trim(strZeile0)) <> LCase(Trim(strZeile1)) Then 'Dateiliste hat sich verändert 
93.
 
94.
	' Hinzugekommene Dateien in "Hinzu1" schreiben 
95.
	Hinzu1 = "" 
96.
	For i = 0 To UBound(Zeile1) 
97.
		Hinzu = Filter(Zeile0, Zeile1(i), True) 
98.
		If UBound(Hinzu) = -1 Then Hinzu1 = Hinzu1 & vbCrLF & Zeile1(i) 
99.
	Next 
100.
	 
101.
	If Hinzu1 <> "" Then 'Es sind Dateien hinzugekommen 
102.
		' Event für hinzugekommene Dateien in das Logbuch schreiben 
103.
		EventStr = "Neu hinzugekommene Dateien vom Typ " & FILEMASK & " :" 
104.
		EventStr = EventStr & Hinzu1 
105.
'		 objShell.LogEvent NEWEVENT, EventStr 
106.
		WScript.Echo("EventHinzu: " & EventStr & vbCrLF) 'zu Demozwecken Ausgabe anstatt Event-Eintrag 
107.
	End If 'Es sind Dateien hinzugekommen 
108.
 
109.
	If NewDel = 1 Then 'Auch gelöschte Dateien protokollieren 
110.
		' Entfernte Dateien in "Weg1" schreiben 
111.
		Weg1 = "" 
112.
		For i = 0 To UBound(Zeile0) 
113.
			Weg = Filter(Zeile1, Zeile0(i), True) 
114.
			If UBound(Weg) = -1 Then Weg1 = Weg1 & vbCrLF & Zeile0(i) 
115.
		Next 
116.
 
117.
		If Weg1 <> "" Then 'Es wurden Dateien entfernt 
118.
		' Event für entfernte Dateien in das Logbuch schreiben 
119.
			EventStr = "Entfernte Dateien vom Typ " & FILEMASK & " :" 
120.
			EventStr = EventStr & Weg1 
121.
'			objShell.LogEvent DELEVENT, EventStr 
122.
			WScript.Echo("EventWeg: " & EventStr & vbCrLF) 'zu Demozwecken Ausgabe anstatt Event-Eintrag 
123.
		End If  'Es wurden Dateien entfernt 
124.
	End If 'Auch gelöschte Dateien protokollieren 
125.
 
126.
Else 
127.
	WScript.Echo "Keine Unterschiede gefunden!" 'Ausgabe zu Demozwecken 
128.
End If 'Dateiliste hat sich verändert
Eigentlich genügt es, die jeweils letzte Dateiliste zwischenzuspeichern - damit entfällt auch die Verwendung des Schalters (der Schalter-Datei). Realisieren lässt sich dies, indem das Ergebnis des aktuellen "Dir"-Befehles unter Verwendung von "Shell.Exec" und "StdOut" gleich in eine Variable eingelesen, per "Split" auf Zeilen aufgeteilt und nach dem Einlesen der alten Liste am Stück in die Datei geschrieben wird.

Erforderlich ist es IMHO, sich gegen das Einlesen einer leeren Dateiliste abzusichern. Auch in dieser Version noch nicht enthalten ist eine Überprüfung des Zielverzeichnisses auf Schreibrechte.

Da ich gerne "ReDim Preserve" vermeide, verwende ich zum Einlesen von Textdateien die dargestellte "ReadAll"-"Split"-Variante - ob es in diesem Fall tatsächlich Performance-Vorteile bringt, lasse ich einmal dahingestellt.

Analog dazu können die Ausgabezeilen in Strings gesammelt werden (da sie ja später ohnehin ge"join"ed werden sollen). Dadurch wird auch noch ein Zähler / Schalter eingespart.

Gleichfalls einsparen lässt sich - durch den Vorab-Vergleich der (in je einem String konzentrierten) alten und neuen Dateiliste - für den Fall, dass sich der Verzeichnisinhalt nicht geändert hat, der Durchlauf der Dateilisten-Arrays. Die Ausgabe eines Hinweises bei unveränderter Dateiliste habe ich nur zu Demozwecken eingebaut.

Schließlich kann Erstellung und Ausgabe des Protokolls für gelöschte Dateien auch in einem einzigen "If" abgewickelt werden.

Grüße
bastla
Bitte warten ..
Mitglied: Bitsqueezer
04.11.2007 um 16:07 Uhr
Hallo Bastla,

vielen Dank für Deine schnelle Anpassung des Scripts - ist in der Tat noch sehr viel besser als meine Version. Je weniger Dateien gelesen/geschrieben werden müssen, desto besser.

Ich bin in VBScript noch nicht so weit, daher kannte ich einige Deiner Techniken noch nicht. Beispielsweise wußte ich noch nicht, daß man die DOS-Ausgaben auch wieder zurück an VBScript umleiten kann. Gute Idee!

Habe Deine Scriptverbesserung bei mir getestet, geht ohne Probleme.

Gruß

Christian
Bitte warten ..
Mitglied: Bitsqueezer
04.11.2007 um 23:51 Uhr
Hallo Bastla,

habe heute dann auch mal versucht, das Script als Rule in SCOM einzubauen. Leider gab es dabei Probleme.

1. Offenbar schnallt ein Script unter SCOM keine CMD-Variablen, daher muß man das %windir% gegen einen festen Pfad "C:\Windows" ersetzen, dann wird zumindest der DIR-Befehl richtig ausgeführt.
2. Nach diversen Tests mit meinem alten und Deinem Script zeigte sich, daß mein altes Script die entsprechenden Events erzeugt, während Dein Script zwar die Content.txt erzeugt, der Inhalt aber immer leer ist. Ich vermute, das SCOM ein Problem damit hat, die Ausgabe des CMD wieder an das Script zurückzuleiten.
3. Auch mein altes Skript hat irgendwo noch eine Macke. Wärhend es beim Direktaufruf funktioniert, hat es sich jetzt entschieden, sich in seiner Funktion umzukehren. Wenn ich eine Datei hinzufüge, wird sie als entfernt bezeichnet und umgekehrt. Irgendwo ist da noch ein kleiner Bug...

Gruß

Christian
Bitte warten ..
Mitglied: bastla
05.11.2007 um 07:09 Uhr
Hallo Bitsqueezer!

Kurzer Hinweis zu 1.: Du könntest es so versuchen:
01.
strCMD = objShell.ExpandEnvironmentStrings("%WinDir%") & "\system32\cmd.exe /c dir " & LOGDIR & "\" & FILEMASK & " /b /od /a-d 2>nul"
oder etwas eleganter:
01.
strCMD = objShell.ExpandEnvironmentStrings("%ComSpec%") & " /c dir " & LOGDIR & "\" & FILEMASK & " /b /od /a-d 2>nul"
wobei aber eigentlich die "cmd.exe" über %PATH% gefunden werden müsste und die Angabe des "System32"-Pfades kaum nötig sein sollte (aber sicher ist sicher).

2. und 3. kann ich mir erst später ansehen ...

Grüße
bastla

[Edit] Ergänzung der Variante mit %ComSpec% und Anpassung des "dir"-Befehles [/Edit]
Bitte warten ..
Mitglied: goodbytes
30.01.2008 um 14:35 Uhr
Hallo,
ein prima Script, echt!
Ich benutze es zur Ordnerüberwachung ob eine Datei hinzugefügt wurde.
Habe die Schleife für gelöschte Dateien rausgemacht.

Torsten
Bitte warten ..
Mitglied: Bitsqueezer
30.01.2008 um 18:48 Uhr
Hallo,

es gibt übrigens noch eine elegante Variante, an das richtige Verzeichnis zu kommen - ganz ohne DOS-Variablen:

01.
Const WINFOLDER = 0 
02.
Set objFSO   = CreateObject("Scripting.FileSystemObject") 
03.
strWinDir = objFSO.GetSpecialFolder(WINFOLDER).Path
Je nach Typ kann man auch den Temp- (1) oder System32-Folder (2) bekommen.

Gruß

Christian
Bitte warten ..
Mitglied: bastla
30.01.2008 um 18:56 Uhr
@Bitsqueezer

Je nach Typ kann man auch den Temp- (1) oder System32-Folder (2) bekommen.
Dann wäre eigentlich in diesem Fall der Ordner "System32" vorzuziehen - der Wert dafür ist allerdings 1; mit 2 erhältst Du den "Temp"-Ordner ...

Grüße
bastla
Bitte warten ..
Mitglied: goodbytes
31.01.2008 um 19:29 Uhr
Ich löse dann bei einer Änderung mittels Batch paar verschiedene Ereignisse aus (ein kurzes "net send" und eine Mail per SMTP mit Hilfe des kleinen Tools "sendmail.exe").

Darüber halt:

Set WSHShell = WScript.CreateObject("WScript.Shell") 'Batch-Datei an Eingabeaufforderung übergeben
WSHShell.Run("cmd.exe /c meinebatch.cmd"), 0, True

Kann ich denn die neu hinzugekommenen Dateien in dem überwachten Ordner in eine Variable speichern und irgendwie der aufgerufenen Batch übergeben?

Ich möchte diese Variable bei "net send" und im Body bei "sendmail.exe" weiterbenutzen.
Bitte warten ..
Mitglied: bastla
31.01.2008 um 19:44 Uhr
Hallo TorstenB!

Kann ich denn die neu hinzugekommenen Dateien in dem überwachten Ordner in eine Variable speichern und irgendwie der aufgerufenen Batch übergeben?
Die hinzugekommenen Dateien werden in der VBS-Variablen "Hinzu1" gespeichert, allerdings mit Zeilenschaltungen, was für die Übergabe in eine Batch-Variable hinderlich ist. Mit der folgenden Zeile kannst Du sie aber trotzdem ausgeben:
01.
WScript.Echo Mid(Replace(Hinzu1, vbCrLF, ";"), 2)
In eine Batch-Variable bekommst Du sie dann so:
01.
for /f "delims=" %%i in ('cscript //nologo C:\Scripts\DeinScriptName.vbs') do set "Neue=%%i"
Soferne es sich um eine kleinere Anzahl von Dateien handelt, sollte es so klappen (wobei zu beachten ist, dass es dann keine weiteren "WScript.Echo"-Befehle geben darf), ansonsten würde es sich anbieten, sie in eine Textdatei zu schreiben:
01.
objFSO.OpenTextFile("D:\NeueDateien.txt", 2, True).Write Mid(Replace(Hinzu1, vbCrLF, ";"), 2)
Den Namen des Textfiles solltest Du natürlich besser als Konstante festlegen (vgl etwa "DIRFILE").

Grüße
bastla
Bitte warten ..
Mitglied: goodbytes
31.01.2008 um 20:00 Uhr
Hallo bastla,
vielen Dank, ich werds morgen früh gleich mal probieren.
Normalerweise kann es auch nicht so viel werden; das Script läuft alle 15min und in der Zeit dürften wenns hoch kommt drei Dateien reinkommen.

Einen schönen Abend noch !!!

Torsten
Bitte warten ..
Mitglied: aschinnerl
21.03.2008 um 16:53 Uhr
Ich habe das Problem das immer in einem Verzeichnis Ordner gelöscht werden. Kann ich mit dem Script den Hauptordner überwachen so das ich verstellen kann wer den Ordner gelöscht hat?
Bitte warten ..
Mitglied: bastla
21.03.2008 um 17:32 Uhr
Hallo aschinnerl!

Soferne ich Dein Vorhaben richtig interpretiere, wäre es sinnvoll, einen neuen Thread zu starten - hier geht es nur darum, generell festzustellen, dass sich der Inhalt eines Ordners geändert hat, und nicht um die Frage, wer die Änderung verursacht hat.

Grüße
bastla
Bitte warten ..
Mitglied: goodbytes
09.05.2008 um 12:28 Uhr
Hallo,
wie könnte ich es denn anstellen, das das Script nicht überprüft, ob neue Dateien hinzugekommen sind, sondern ob beim Lauf noch Dateien darin liegen, welche beim letzten Lauf schon drin waren. Wenn mindestens eine gefunden wird soll die Batch ausgeführt werden.

Hintergrund: Ein POP3-Connector holt die Mails vom Provider ab und übergibt sie dem Exchange-Server. Beim Abholen landen die Mails temporär in einem Ordner, bevor sie nacheinander an den Exchange übergeben werden. Wenn bei dieser Übergabe was schiefgeht bleiben diese Dateien hier liegen. In diesem Fall soll die Batch ausgelöst werden. Es muss also genau die Dateinamen in der Liste mit denen in dem TEMP-Ordner überprüft werden.

Hier mein momentanes Script:

' Ordnerüberwachung:

' Art der verwendeten Logbucheinträge, 0 = Success, 1 = Error, 2 = Warning, 4 = Information
NEWEVENT = 1
DELEVENT = 2

' Verzeichnis, in dem die Dateien protokolliert werden sollen
LOGDIR = "C:\TMP\"
' Dateien, die gesucht werden sollen
FILEMASK = "*.msg"

' Art der verwendeten Logbucheinträge, 0 = Success, 1 = Error, 2 = Warning, 4 = Information
NEWEVENT = 1
DELEVENT = 2

' Diese temporäre Datei wird für den Vergleich benötigt. Das Script muss im verwendeten Verzeichnis Schreibrechte haben.
DIRFILE = "C:\Programme\POPcon\Log.txt"

' NewDel = 1: Alle Unterschiede protokollieren
' NewDel = 0: Nur neu hinzugekommene Dateien protokollieren
NewDel = 1

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objShell = CreateObject("WScript.Shell")

'Alte Liste aus DIRFILE in Array Zeile0() einlesen
If objFSO.FileExists(DIRFILE) Then 'DIRFILE vorhanden
Set objDirFile = objFSO.OpenTextFile(DIRFILE, 1)
If Not objDirFile.AtEndOfStream Then 'DIRFILE nicht leer
strZeile0 = objDirFile.ReadAll
Zeile0 = Split(strZeile0, vbCrLF)
Else
Zeile0 = Array("")
End If 'DIRFILE nicht leer
Else
Zeile0 = Array("")
End If 'DIRFILE vorhanden

' Alle Err-Dateien aus dem Ordner sortiert in das Array Zeile1() einlesen
strCMD = objShell.ExpandEnvironmentStrings("%ComSpec%") & " /c dir " & LOGDIR & "\" & FILEMASK & " /b /od /a-d 2>nul"
strZeile1 = objShell.Exec(strCMD).StdOut.ReadAll
Zeile1 = Split(strZeile1, vbCrLF)

' Am Ende der Ausführung aktuelle Dateiliste in DIRFILE speichern
objFSO.OpenTextFile(DIRFILE, 2, True).Write strZeile1

' *
' Dateivergleich zwischen Content.txt (Zeile0) und aktueller Liste (Zeile1)
' *

If LCase(Trim(strZeile0)) <> LCase(Trim(strZeile1)) Then 'Dateiliste hat sich verändert

' Hinzugekommene Dateien in "Hinzu1" schreiben
Hinzu1 = ""
For i = 0 To UBound(Zeile1)
Hinzu = Filter(Zeile0, Zeile1(i), True)
If UBound(Hinzu) = -1 Then Hinzu1 = Hinzu1 & vbCrLF & Zeile1(i)
Next

If Hinzu1 <> "" Then 'Es sind Dateien hinzugekommen
' Event für hinzugekommene Dateien in das Logbuch schreiben
EventStr = "Neu hinzugekommene Dateien vom Typ " & FILEMASK & " :"
EventStr = EventStr & Hinzu1
' objShell.LogEvent NEWEVENT, EventStr
'WScript.Echo("EventHinzu: " & EventStr & vbCrLF) 'zu Demozwecken Ausgabe anstatt Event-Eintrag
Set WSHShell = WScript.CreateObject("WScript.Shell") 'Batch-Datei an Eingabeaufforderung übergeben
WSHShell.Run("cmd.exe /c MeineBatch.cmd"), 0, True
End If 'Es sind Dateien hinzugekommen

Else
'WScript.Echo "Keine Unterschiede gefunden!" 'Ausgabe zu Demozwecken
End If 'Dateiliste hat sich verändert

Torsten
Bitte warten ..
Mitglied: goodbytes
14.05.2008, aktualisiert 18.10.2012
Die Lösung zu diesem Problem befindet sich hier.
Vielen Dank nochmal an bastla !!!

Torsten
Bitte warten ..
Neuester Wissensbeitrag
Windows 10

Powershell 5 BSOD

(8)

Tipp von agowa338 zum Thema Windows 10 ...

Ähnliche Inhalte
Batch & Shell
gelöst Appx aus Image auslesen und entfernen (9)

Frage von Markus2016 zum Thema Batch & Shell ...

Heiß diskutierte Inhalte
Microsoft
Ordner mit LW-Buchstaben versehen und benennen (20)

Frage von Xaero1982 zum Thema Microsoft ...

Outlook & Mail
gelöst Outlook 2010 findet ost datei nicht (19)

Frage von Floh21 zum Thema Outlook & Mail ...

Netzwerkmanagement
gelöst Anregungen, kleiner Betrieb, IT-Umgebung (18)

Frage von Unwichtig zum Thema Netzwerkmanagement ...

Festplatten, SSD, Raid
M.2 SSD wird nicht erkannt (14)

Frage von uridium69 zum Thema Festplatten, SSD, Raid ...