读取特定的 Windows 事件日志事件

问题描述 投票:0回答:4

我正在开发一个程序,需要知道如何根据该脚本已有的记录号读取 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
python windows event-log
4个回答
16
投票

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

您还可以编写自定义查询,这允许您通过可以编写脚本的任何 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()

十年后

虽然这仍然有效,但我建议任何偶然发现它的人参考线程中的这个答案以获得更好的解决方案。


11
投票

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

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

10
投票

不!没有可用的函数可以让您根据事件 id 获取事件。

参考:事件记录功能

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

这与您正在做的方式相同,但更简洁


1
投票

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

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 扩展的简洁说明 http://timgolden.me.uk/pywin32-docs/contents.html

© www.soinside.com 2019 - 2024. All rights reserved.