Jak uzyskać tylko ostatni rekord zapisany w dzienniku?
Skrypciarze odpowiadają na Wasze pytania
Witamy w rubryce TechNet, w której Skrypciarze z firmy Microsoft odpowiadają na częste pytania dotyczące używania skryptów w administracji systemu. Jeśli macie jakieś pytania z tej dziedziny, zachęcamy do wysłania e-maila na adres: scripter@microsoft.com. Nie możemy zagwarantować odpowiedzi na każde otrzymane pytanie, ale staramy się jak możemy. |
Jak uzyskać tylko ostatni rekord zapisany w dzienniku?
Cześć Skrypciarzu! W jaki sposób mogę przeczytać tylko ostatni rekord zapisany w dzienniku zdarzeń? Innymi słowy, jaki jest ekwiwalent WMI dla instrukcji SQL Select Top 1?
-- KM
Cześć KM. Jak się okazuje, WMI nie posiada żadnego ekwiwalentu komendy Select Top. WQL (WMI Query Language – język zapytań WMI) jest wyposażony jedynie w niewielki podzbiór komend występujących w SQL. Nie oznacza to oczywiście, że nie jesteśmy w stanie uzyskać tylko ostatniego rekordu zapisanego w dzienniku zdarzeń; oznacza to tylko tyle, że musimy się do tego zabrać sposobem.
Aby uzyskać tylko ostatni rekord, musimy zrobić dwie rzeczy. Po pierwsze, musimy sprawdzić liczbę rekordów w dzienniku zdarzeń. To istotna informacja, ponieważ przy dodawaniu do dziennika zdarzenia są numerowane sekwencyjnie; innymi słowy pierwsze zdarzenie zapisane w dzienniku będzie rekordem 1, drugie rekordem 2, i tak dalej. Jeśli w dzienniku znajduje się 4912 elementów, to ostatni rekord zapisany w dzienniku będzie nosił numer 4912. Kiedy już poznamy liczbę wszystkich rekordów, możemy utworzyć zapytanie, które zwróci tylko zdarzenia z numerem rekordu równym liczbie wszystkich rekordów.
Poniżej masz niewielki, prosty skrypt, który określa całkowitą liczbę rekordów w dzienniku zdarzeń Application, a wartość przechowuje w zmiennej intRecords:
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set objInstalledLogFiles = objWMIService.ExecQuery _
("Select * from Win32_NTEventLogFile Where LogFileName = 'Application'")
For Each objLogfile in objInstalledLogFiles
intRecords = objLogFile.NumberOfRecords
Next
Teraz potrzebujemy zapytania, które zwróci wszystkie zdarzenia z dziennika zdarzeń Application (aplikacja), w których wartość RecordNumber (numer rekordu) jest równa wartości intRecords (będzie tylko jeden taki rekord, jako, że numery rekordów są unikalne):
Set colLoggedEvents = objWMIService.ExecQuery _
("Select * From Win32_NTLogEvent Where Logfile = 'Application' AND " & _
"RecordNumber = " & intRecords)
Pozostaje nam tylko połączyć ze sobą te dwa fragmenty skryptów, a następnie dodać pętlę For Each (dla każdego), w której wywołujemy echo właściwości tego rekordu:
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set objInstalledLogFiles = objWMIService.ExecQuery _
("Select * from Win32_NTEventLogFile Where LogFileName = 'Application'")
For Each objLogfile in objInstalledLogFiles
intRecords = objLogFile.NumberOfRecords
Next
Set colLoggedEvents = objWMIService.ExecQuery _
("Select * From Win32_NTLogEvent Where Logfile = 'Application' AND " & _
"RecordNumber = " & intRecords)
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
To powinno załatwić sprawę.
Do początku strony