【问题标题】:Read Specific Windows Event Log Event读取特定的 Windows 事件日志事件
【发布时间】:2012-06-27 03:59:44
【问题描述】:

我正在开发一个程序,并且需要知道如何根据记录号读取 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

【问题讨论】:

  • 完成后记得致电win32evtlog.CloseEventLog(hand)

标签: python windows event-log


【解决方案1】:

我意识到这是一个老问题,但我遇到了它,如果我遇到了,其他人也可能。

您还可以编写自定义查询,它允许您通过您可以编写脚本的任何 WMI 参数(包括事件 ID)进行查询。它还有一个好处是可以让您退出并清除所有存在的 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()

【讨论】:

  • 考虑将实际代码添加到您的答案中,并将链接仅作为参考。您想让答案自成一体,因为您不知道这些链接何时到期。
  • 感谢您的建议 - 我已经这样做了。
【解决方案2】:

不!没有可用的函数可让您根据事件 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

这和你做的一样,但更简洁

【讨论】:

  • 太棒了!不久前我发现了这些信息!感谢您的回答,我会尽快接受。
  • 我不知道发布此答案时的状态,但这不再正确(请参阅下面我的答案 - 如果您可以编写 WMI 查询,您可以查询它)。
  • EventID 是一个整数。它永远不会匹配字符串“27035”
【解决方案3】:

现在有一个 python 库(python 3 及更高版本)可以满足您的要求,称为winevt。您正在寻找的内容可以通过以下方式完成:

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

【讨论】:

    【解决方案4】:

    我看到答案已经涵盖了这些问题。但是我想补充一点,如果您需要检索事件创建时间的特定日志,您可以执行以下操作:

    import win32evtlog
    from lxml import objectify
    from datetime import datetime, timezone
    
    
    def get_events(task_name, events_num):
    
        """
        task_name: a string from windows logs. e.g: "Microsoft-Windows-LanguagePackSetup/Operational"
        events_num: an integer for numbers of time creation. example: 10
        Output sample: 2022-03-09 08:45:29
        """
        handle = win32evtlog.EvtQuery(task_name, win32evtlog.EvtQueryReverseDirection , "*")
        event = win32evtlog.EvtNext(handle, 70, -1, 0)
        for i in event[-events_num:]:
            root = objectify.fromstring(win32evtlog.EvtRender(i, 1)) 
            paras =  root.System.TimeCreated
            d = datetime.fromisoformat(paras.attrib['SystemTime'][:23]).astimezone(timezone.utc)
            print(d.strftime('%Y-%m-%d %H:%M:%S'))
    
    task_name = input("Enter the task name (e.g. Microsoft-Windows-ReadyBoost/Operational)")
    events_num = int(input("Enter the number of logs"))
    result = get_events(task_name, events_num)
    
    
    if __name__ == "__main__": 
        print(result)
    
    

    这是获取特定日志的好方法。您可以获取更多信息,而不仅仅是从 XML 文件创建时间。 这个网页提供了对 Win32 Extensions 的简洁解释http://timgolden.me.uk/pywin32-docs/contents.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多