2012-06-27 166 views
7

我正在研究一個程序,並且需要知道如何根據記錄編號讀取Windows事件日誌的特定條目,該腳本已具有此記錄編號。以下是我一直在使用的代碼,但我不想循環所有事件,直到找到我正在尋找的代碼。有任何想法嗎?閱讀特定的Windows事件日誌事件

import win32evtlog 

server = 'localhost' # name of the target computer to get event logs 
logtype = 'System' 
hand = win32evtlog.OpenEventLog(server,logtype) 
flags = win32evtlog.EVENTLOG_BACKWARDS_READ|win32evtlog.EVENTLOG_SEQUENTIAL_READ 
total = win32evtlog.GetNumberOfEventLogRecords(hand) 

while True: 
    events = win32evtlog.ReadEventLog(hand, flags,0) 
    if events: 
     for event in events: 
      if event.EventID == "27035": 
       print 'Event Category:', event.EventCategory 
       print 'Time Generated:', event.TimeGenerated 
       print 'Source Name:', event.SourceName 
       print 'Event ID:', event.EventID 
       print 'Event Type:', event.EventType 
       data = event.StringInserts 
       if data: 
        print 'Event Data:' 
        for msg in data: 
         print msg 
       break 
+0

記得撥打'win32evtlog.CloseEventLog(手)'時,即可大功告成。 – twasbrillig

回答

3

不!沒有可用的功能可以根據事件ID獲取事件。

參考:Event logging functions

GetNumberOfEventLogRecords Retrieves the number of records in the specified event log. 
GetOldestEventLogRecord  Retrieves the absolute record number of the oldest record 
          in the specified event log. 
NotifyChangeEventLog  Enables an application to receive notification when an event 
          is written to the specified event log. 

ReadEventLog    Reads a whole number of entries from the specified event log. 
RegisterEventSource   Retrieves a registered handle to the specified event log. 

只有其他感興趣的方法是閱讀最早的事件。

您必須通過結果的任何方式進行迭代,你的做法是正確的:)

你只能改變你的做法像下面的形式,但是這是不必要的。

events = win32evtlog.ReadEventLog(hand, flags,0) 
events_list = [event for event in events if event.EventID == "27035"] 
if event_list: 
    print 'Event Category:', events_list[0].EventCategory 

這就像你正在做的,但更簡潔的相同方式

+0

太棒了!我不久前發現了這些信息!謝謝你的回答,我會盡我所能接受。 –

+0

我不知道這個答案發布時的狀態是什麼,但這不再正確(請參閱下面的答案 - 如果您可以編寫WMI查詢,則可以查詢它)。 –

+0

EventID是一個整數。它永遠不會匹配字符串「27035」 – wojtow

6

我意識到這是一個老問題,但我碰到它,如果我這樣做,其他人可能也。

您也可以編寫自定義查詢,它允許您通過任何可以腳本(包括事件ID)的WMI參數進行查詢。它還具有讓您拔出並清除所有那些VBS WMI查詢的好處。我實際上比其他任何人更頻繁地使用此功能。例如,請參見:

下面就來查詢應用程序日誌中的特定事件的樣本。我沒有充實它,但是您也可以構建一個WMI時間字符串並查詢特定日期/時間之間或之後的事件。

#! py -3 

import wmi 

def main(): 
    rval = 0 # Default: Check passes. 

    # Initialize WMI objects and query. 
    wmi_o = wmi.WMI('.') 
    wql = ("SELECT * FROM Win32_NTLogEvent WHERE Logfile=" 
      "'Application' AND EventCode='3036'") 

    # Query WMI object. 
    wql_r = wmi_o.query(wql) 

    if len(wql_r): 
     rval = -1 # Check fails. 

    return rval 



if __name__ == '__main__': 
    main() 
+0

考慮將實際代碼添加到您的答案中,並僅將鏈接作爲參考。您想讓答案自成一體,因爲您不知道這些鏈接何時到期。 – rayryeng

+0

感謝您的建議 - 我已經完成了這一步。 –

0

現在有一個python庫可以做你要求的winevt。您正在尋找可通過以下做些什麼:

from winevt import EventLog 
query = EventLog.Query("System","Event/System[EventID=27035]") 
event = next(query)