11234
23.03.2006, aktualisiert am 15.04.2008
27897
19
0
Ereignisanzeige auslesen und in *.txt-Datei schreiben
Hi,
ich möchte ein VBSkript haben, welches die Ereignisanzeige ausließt und anschließend in eine Textdatei schreibt. Leider habe ich nirgends Beispiel dafür gefunden und einen Ansatz dazu ist mir bisher auch fern geblieben ;)
Wäre super wenn ihr mir helfen könntet.
Mir freundlichen Grüßen
ich möchte ein VBSkript haben, welches die Ereignisanzeige ausließt und anschließend in eine Textdatei schreibt. Leider habe ich nirgends Beispiel dafür gefunden und einen Ansatz dazu ist mir bisher auch fern geblieben ;)
Wäre super wenn ihr mir helfen könntet.
Mir freundlichen Grüßen
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 28805
Url: https://administrator.de/forum/ereignisanzeige-auslesen-und-in-txt-datei-schreiben-28805.html
Ausgedruckt am: 22.12.2024 um 22:12 Uhr
19 Kommentare
Neuester Kommentar
Hi, da gibt es von M$ ein Tool:
dumpel.exe
http://www.microsoft.com/windows2000/techinfo/reskit/tools/existing/dum ...
Grüße
Dieter
dumpel.exe
http://www.microsoft.com/windows2000/techinfo/reskit/tools/existing/dum ...
Grüße
Dieter
Grüß Dich Felix, (alddA Namensvetter *gg*)
Du verwendest ja bereits die richtige Klasse, also ein Blick auf die EventType-Eigenschaft und Dein Problem ist gelöst :
'Auszug aus dem MSDN (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk ..)
EventType
Data type: uint8
Access type: Read-only
Windows Server 2003, Windows 2000, and Windows XP: Type of event.
Value Meaning
1 Error
2 Warning
3 Information
4 Security audit success
5 Security audit failure
Dieser Code hat bei mir einwandfrei (in VBA) funktioniert:
Wie und wo Du Deinem Array die Werte zuweist hängt natürlich von Dir ab.
Und bitte nicht irgendwie /angemacht/ fühlen. Wenn jemand Mal ein gleiches Problem hat und diesen Post hier ohne Lösung liest...
War ja auch keineswegs böse gemeint, oder so.
Auf jeden Fall hoffe ich das Dir das hier hilft.
Grüße
Felix
Du verwendest ja bereits die richtige Klasse, also ein Blick auf die EventType-Eigenschaft und Dein Problem ist gelöst :
'Auszug aus dem MSDN (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk ..)
EventType
Data type: uint8
Access type: Read-only
Windows Server 2003, Windows 2000, and Windows XP: Type of event.
Value Meaning
1 Error
2 Warning
3 Information
4 Security audit success
5 Security audit failure
Dieser Code hat bei mir einwandfrei (in VBA) funktioniert:
Public Function xxx()
Dim strComputer As String
Dim objWMIService As Object
Dim colLoggedEvents As Object
Dim objEvent As Object
Dim i As Integer
Dim FILTERED As Boolean
Dim DeinArrayMitEventTypeIntegers(0 To 1) As Integer
DeinArrayMitEventTypeIntegers(0) = 3
DeinArrayMitEventTypeIntegers(1) = 2
strComputer = "."
Set objWMIService = GetObject("winmgmts:" & "\\" & strComputer & "\root\cimv2")
Set colLoggedEvents = objWMIService.ExecQuery("Select * from Win32_NTLogEvent Where Logfile = 'Application'")
For Each objEvent In colLoggedEvents
For i = LBound(DeinArrayMitEventTypeIntegers) To UBound(DeinArrayMitEventTypeIntegers)
If (objEvent.EventType = DeinArrayMitEventTypeIntegers(i)) Then FILTERED = True
Next i
If Not FILTERED Then
Debug.Print "Category: " & objEvent.Category
Debug.Print "Computer Name: " & objEvent.ComputerName
Debug.Print "Event Code: " & objEvent.EventCode
Debug.Print "Message: " & objEvent.Message
Debug.Print "Record Number: " & objEvent.RecordNumber
Debug.Print "Source Name: " & objEvent.SourceName
Debug.Print "Time Written: " & objEvent.TimeWritten
Debug.Print "Event Type: " & objEvent.Type
Debug.Print "User: " & objEvent.User
End If
FILTERED = False
Next objEvent
End Function
Wie und wo Du Deinem Array die Werte zuweist hängt natürlich von Dir ab.
Und bitte nicht irgendwie /angemacht/ fühlen. Wenn jemand Mal ein gleiches Problem hat und diesen Post hier ohne Lösung liest...
War ja auch keineswegs böse gemeint, oder so.
Auf jeden Fall hoffe ich das Dir das hier hilft.
Grüße
Felix
So,
habe mich Mal ein bischen mit VBScript beschäftigt. Ist mir ja auch peinlich das ich das vorher noch nie gemacht hab...
Das sollte eigtl geeignet sein. Du müßtest halt noch evtl näher beschreiben wie die Daten in der XML-File gespeichert werden, und wie Du die auslesen willst um das Array zu befüllen. Also ich sehe da keine großen Probleme...
Hier mal die .VBS - File die ich zusammengeschreibselt hab. Habe ich mit Windows-Editor getippt und zu "tode geärgert" *aargh*
habe mich Mal ein bischen mit VBScript beschäftigt. Ist mir ja auch peinlich das ich das vorher noch nie gemacht hab...
Das sollte eigtl geeignet sein. Du müßtest halt noch evtl näher beschreiben wie die Daten in der XML-File gespeichert werden, und wie Du die auslesen willst um das Array zu befüllen. Also ich sehe da keine großen Probleme...
Hier mal die .VBS - File die ich zusammengeschreibselt hab. Habe ich mit Windows-Editor getippt und zu "tode geärgert" *aargh*
Dim DeinArrayMitEventTypeIntegers(1)
DeinArrayMitEventTypeIntegers(0) = 1
DeinArrayMitEventTypeIntegers(1) = 1
Call outputEventsToFile("C:\Test.txt","Application",DeinArrayMitEventTypeIntegers)
Public Sub outputEventsToFile(ByVal filename,ByVal LogFileType,ByVal filteredEvents())
On Error Resume Next
Dim strComputer
Dim objWMIService
Dim colLoggedEvents
Dim objEvent
Dim i
Dim FILTERED
Dim fso, f
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.OpenTextFile(filename, 2, True)
strComputer = "."
Set objWMIService = GetObject("winmgmts:" & "\\" & strComputer & "\root\cimv2")
Set colLoggedEvents = objWMIService.ExecQuery("Select * from Win32_NTLogEvent Where Logfile = '" & LogFileType & "'")
For Each objEvent In colLoggedEvents
For i = LBound(DeinArrayMitEventTypeIntegers) To UBound(DeinArrayMitEventTypeIntegers)
If (objEvent.EventType = DeinArrayMitEventTypeIntegers(i)) Then
FILTERED = True
Exit For
End If
Next
If Not FILTERED Then
f.WriteLine( "Category: " & objEvent.Category)
f.WriteLine "Computer Name: " & objEvent.ComputerName
f.WriteLine "Event Code: " & objEvent.EventCode
f.WriteLine "Message: " & objEvent.Message
f.WriteLine "Record Number: " & objEvent.RecordNumber
f.WriteLine "Source Name: " & objEvent.SourceName
f.WriteLine "Time Written: " & objEvent.TimeWritten
f.WriteLine "Event Type: " & objEvent.Type
f.WriteLine "User: " & objEvent.User
End If
FILTERED = False
Next
f.Close
End Sub
Na, Ihr Felixe,
@misterdemeanor,
ich glaube, Deine Lösung geht ein wenig an der eigentlichen "kleinen" Frage vorbei.
Und außerdem sollte ja IMHO ein Ziel sein, schon im SELECT-String möglichst die Menge an Daten einzuschränken/zu filtern und nicht immer das ganze Eriegnisprotokoll zu holen und danach zu entscheiden, ob einzelne Sätze für Anzeige oder Ausdruck unterdrückt werden.
@11234
Du hast einen "falschen" SQL-String zusammengebastelt, da Du Strings im String hast. Das ist alles.
ALT:
"Select * from Win32_NTLogEvent Where Logfile = 'Application' WHERE EventType <> Filter(i)"
NEU:
"Select * from Win32_NTLogEvent Where Logfile = 'Application' WHERE EventType <> ' " & Filter(i) & " ' "
Oder, mal im Zusammenhang im Schnipsel:
Gruß
Biber
@misterdemeanor,
ich glaube, Deine Lösung geht ein wenig an der eigentlichen "kleinen" Frage vorbei.
Und außerdem sollte ja IMHO ein Ziel sein, schon im SELECT-String möglichst die Menge an Daten einzuschränken/zu filtern und nicht immer das ganze Eriegnisprotokoll zu holen und danach zu entscheiden, ob einzelne Sätze für Anzeige oder Ausdruck unterdrückt werden.
@11234
Du hast einen "falschen" SQL-String zusammengebastelt, da Du Strings im String hast. Das ist alles.
ALT:
"Select * from Win32_NTLogEvent Where Logfile = 'Application' WHERE EventType <> Filter(i)"
NEU:
"Select * from Win32_NTLogEvent Where Logfile = 'Application' WHERE EventType <> ' " & Filter(i) & " ' "
Oder, mal im Zusammenhang im Schnipsel:
CONST EVENTTYPE_ERROR = "1"
CONST EVENTTYPE_WARNING = "2"
CONST EVENTTYPE_INFORMATION = "3"
CONST EVENTTYPE_SUCCESSAUDIT = "4"
CONST EVENTTYPE_FAILUREAUDIT = "5"
strComputer = "."
arrEventType = array( EVENTTYPE_ERROR, EVENTTYPE_WARNING , EVENTTYPE_FAILUREAUDIT)
Set objWMIService = GetObject("winmgmts:" & "\\" & strComputer & "\root\cimv2")
strSelect = "Select * from Win32_NTLogEvent Where Logfile = 'Application'"
'--------------------> hier 4 Beispiele für das Zusammenbasteln des SELECT-Strings
'--------------------> wahlweise auskommentieren
' Set colLoggedEvents = objWMIService.ExecQuery (strSelect & " AND EventType = '" & "1" & "' ")
' Set colLoggedEvents = objWMIService.ExecQuery (strSelect & " AND EventType = '" & EVENTTYPE_ERROR & "' ")
' Set colLoggedEvents = objWMIService.ExecQuery (strSelect & " AND EventType <> '" & EVENTTYPE_ERROR & "' ")
Set colLoggedEvents = objWMIService.ExecQuery (strSelect & " AND EventType = '" & arrEventType(1) & "' ")
'Remember: arrEventType(1) == EVENTTYPE_WARNING
For Each objEvent In colLoggedEvents
WScript.Echo "Category: " & objEvent.Category
WScript.Echo "Computer Name: " & objEvent.ComputerName
WScript.Echo "Event Code: " & objEvent.EventCode
WScript.Echo "Message: " & objEvent.Message
WScript.Echo "Record Number: " & objEvent.RecordNumber
WScript.Echo "Source Name: " & objEvent.SourceName
WScript.Echo "Time Written: " & objEvent.TimeWritten
WScript.Echo "Event Type: " & objEvent.Type
WScript.Echo "User: " & objEvent.User
Next
'P.S. VBS würde auch zulassen:
'Set colLoggedEvents = objWMIService.ExecQuery (strSelect & " AND EventType = '" & 1 & "' ")
'.... also einen numerischen Wert in den String reinzudrücken...aber dieses "feature" wollte ich mir nicht angewöhnen.
'
Gruß
Biber
Hi Biber,
Na Dein Code sieht schon N bissel sauberer aus als meiner *g*
Aber auch wenn ich meist zu kompliziert und um die Ecke denke *kurzeDenkpause*
glaube ich das Felix *kurzeDenkpause* schon alle in seinem Array enthaltenen Eventtypen
ausschließen möchte.
Also glaube ich das doch eine Schleife von nöten ist in der die Eventtypen die er nicht
haben will ausschließt bzw. umgekehrt.
Das dann gleich in den WHERE String zu basteln wäre natürlich eine /bessere/ Lösung :
Aber vielleicht hab ich Felix *kurzeDenkpause* auch nur einfach falsch verstanden.
Grüße
Felix *kopfkratz*
Na Dein Code sieht schon N bissel sauberer aus als meiner *g*
Aber auch wenn ich meist zu kompliziert und um die Ecke denke *kurzeDenkpause*
glaube ich das Felix *kurzeDenkpause* schon alle in seinem Array enthaltenen Eventtypen
ausschließen möchte.
Also glaube ich das doch eine Schleife von nöten ist in der die Eventtypen die er nicht
haben will ausschließt bzw. umgekehrt.
Das dann gleich in den WHERE String zu basteln wäre natürlich eine /bessere/ Lösung :
...
where = "Logfile='Application' "
For i = LBound([array()]) To UBound([array()])
If i <> UBound([array()]) Then
where = where & " AND EventType<>" & array(i)
End If
Next
...
Aber vielleicht hab ich Felix *kurzeDenkpause* auch nur einfach falsch verstanden.
Grüße
Felix *kopfkratz*
Nein, hast ja schon im Ansatz Recht... (ich aber auch ..*gg)
Wo ich behaupte, Recht zu haben:
Sinnvoller ist es sicher, die Daten schon im SELECT-String einzuschränken.
Und nicht erst alles zu holen und dann nur einen oder zwei der EventTypes zu verwerten.
Wo Du Recht hast:
Klar, man/frau muss über die ganze Arraylänge wackeln und einen "AND"-String anhängen.
Wenn es denn nur ein Array-Element ist. Sonst gehts schief...
Denn wo Du noch danebenfasst:
Deine Bedingung wird ein leeres ResultSet zurückgeben, denn EventType kann ja nie vom Type "1" AND vom Type "2" AND vom Type "3" sein...
Da das doofe M$-WMI-Pseudo-SQL sowas nicht kann:
Where LogFile ='Application' AND Eventtype IN ('1', '2', '4')
...müsste eine ellenlange, aber korrekte zweite WHERE-Klausel so aussehen:
a) ALLE Arrayelemente
...Where LogFile='Application' AND ( EventType='1' OR EventType='2' OR EventType='4' )
b) KEINES der ArrayElemente:
...Where LogFile='Application' AND ( EventType<>'1' AND EventType<>'2' AND EventType<>'4' )
[Edit] ........Zurückruder.... ------------
Du Wolltest ja auch nur alle gewählten AUSschließen... da passt Deine Bedingung in der Tat.
Nur die Mehrere-EINschließen-Bedingung muss mit "OR"s und/oder Zusatz-Klammern gebastelt werden.
Sorry, hatte schneller getippt als gelesen.
Werde mich bessern...
[/Edit]------------
...Also im Prinzip recht strukturiert.
Hatte vorhin beim Testen auch angefangen, zu basteln, aber.... *axelzuck*
..Bei nur 5 EventTypen, bei denen es ohnehin nur 3 real gibt (ERROR, WARNING, INFO)...
... da werde ich für diese paar Kombinationen keine SQL-String-Generier-Funktionen schreiben.
Da warte ich lieber, bis M$ die ..."where IN LISTE.."/ "where NOT IN LISTE" -Syntax einbaut.
Gruß
Biber
*bg*
NAtürlich hast Du Recht!
So ein Lapsus würde mir auch nicht wirklich passieren, erst ALle Daten zu holen und dann anschließen zu "filtern". War durch meinen/äh seinen Namen total verwirrt *bg*
Ne, generell vollkommen richtig die Where Klausel zu spezifizieren, hast Du Recht *gg
Aber meinste denn das M$ noch was an den WMI´s, etc was ändert, bzw. das was bereits in der Referenz steht aber "Not yet implemented" ist hinzufügt?
Grüße
Felix -misterdemeanor-
NAtürlich hast Du Recht!
So ein Lapsus würde mir auch nicht wirklich passieren, erst ALle Daten zu holen und dann anschließen zu "filtern". War durch meinen/äh seinen Namen total verwirrt *bg*
Ne, generell vollkommen richtig die Where Klausel zu spezifizieren, hast Du Recht *gg
Aber meinste denn das M$ noch was an den WMI´s, etc was ändert, bzw. das was bereits in der Referenz steht aber "Not yet implemented" ist hinzufügt?
Grüße
Felix -misterdemeanor-
In SQL gibt es keine Schleifen, richtig.
In dem Code-Schnipsel der For Schleife wird die WHERE Klausel des SQL-Strings zusammengebastelt.
Nach dieser Schleife hast Du dann (entsprechend der Werte im Array) in der Variablen where zB folgenden Text : "Logfile='Application' AND EventType<>1 AND EventType<>3".
Kompletter Code zur Ausgabe wäre dann also :
Du solltest Dir halt im klaren darüber sein das die "ExecQuery([arg])" einen (SQL) String als Argument erwartet. Die Variable sql im obigen Code ist ja nur eine Variable die mit Text gefüllt wird(welcher ein SQL-Statement darstellt) der dann der ExecQuery-Funktion übergeben wird und von dieser dann ausgeführt wird.
In dem Code-Schnipsel der For Schleife wird die WHERE Klausel des SQL-Strings zusammengebastelt.
Nach dieser Schleife hast Du dann (entsprechend der Werte im Array) in der Variablen where zB folgenden Text : "Logfile='Application' AND EventType<>1 AND EventType<>3".
Kompletter Code zur Ausgabe wäre dann also :
On Error Resume Next
filter() = Array(3,2)
sql = "SELECT * FROM Win32_NTLogEvent WHERE LogFile='Application' "
For i = LBound(filter) To UBound(filter)
sql = sql & " AND EventType<>" & filter(i)
Next
Set objWMIService = GetObject("winmgmts:" & "\\.\root\cimv2")
Set colLoggedEvents = objWMIService.ExecQuery(sql)
For Each objEvent In colLoggedEvents
WScript.Echo "Category: " & objEvent.Category
WScript.Echo "Computer Name: " & objEvent.ComputerName
WScript.Echo "Event Code: " & objEvent.EventCode
WScript.Echo "Message: " & objEvent.Message
WScript.Echo "Record Number: " & objEvent.RecordNumber
WScript.Echo "Source Name: " & objEvent.SourceName
WScript.Echo "Time Written: " & objEvent.TimeWritten
WScript.Echo "Event Type: " & objEvent.Type
WScript.Echo "User: " & objEvent.User
Next
Du solltest Dir halt im klaren darüber sein das die "ExecQuery([arg])" einen (SQL) String als Argument erwartet. Die Variable sql im obigen Code ist ja nur eine Variable die mit Text gefüllt wird(welcher ein SQL-Statement darstellt) der dann der ExecQuery-Funktion übergeben wird und von dieser dann ausgeführt wird.
Schade!
Als aller-aller-aller-Erstes hätte Dir "filter" auffallen müssen!
Es ist immerhin ein Schlüsselwort in VBS und sollte mit auskommentierung von "On Error Resume Next" sofort zum stoppen des Scriptes führen.
Nun ja, von dieser "Kleinigkeit" abgesehen sind natürlich noch gut ein dutzend Dinge zu beachten welche einen Fehler auslösen würden.
Da Dir in VBS praktisch keine Fehlerbehandlung möglich ist, musst Du auf alle /Eventualitäten/ eingehen.
Ich lege Dir wirklich ans Herz Dich hier einzulesen.
Sollten DANN noch weitere Fragen auftauchen, sind Biber* und ich sicher immer noch da um Dir unter die Arme zu greifen.
Grüße
Felix
*:Biber wurde ohne Ihres/Seines Wissens in obige Behauptung einbezogen.
Als aller-aller-aller-Erstes hätte Dir "filter" auffallen müssen!
Es ist immerhin ein Schlüsselwort in VBS und sollte mit auskommentierung von "On Error Resume Next" sofort zum stoppen des Scriptes führen.
Nun ja, von dieser "Kleinigkeit" abgesehen sind natürlich noch gut ein dutzend Dinge zu beachten welche einen Fehler auslösen würden.
Da Dir in VBS praktisch keine Fehlerbehandlung möglich ist, musst Du auf alle /Eventualitäten/ eingehen.
Ich lege Dir wirklich ans Herz Dich hier einzulesen.
Sollten DANN noch weitere Fragen auftauchen, sind Biber* und ich sicher immer noch da um Dir unter die Arme zu greifen.
Grüße
Felix
*:Biber wurde ohne Ihres/Seines Wissens in obige Behauptung einbezogen.
@misterdemeanor
Und stehe natürlich auch zur Verfügung.
Gruß
der/die/das Biber
*:Biber wurde ohne Ihres/Seines Wissens in obige Behauptung einbezogen.
"seines Wissens" ist schon okay - ich heiße ja BibER und nicht BibSIE..Und stehe natürlich auch zur Verfügung.
Gruß
der/die/das Biber