Чтение определенного события журнала событий 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

person Zac Brown    schedule 27.06.2012    source источник
comment
Не забудьте позвонить win32evtlog.CloseEventLog(hand), когда закончите.   -  person twasbrillig    schedule 11.01.2016


Ответы (3)


Нет! Нет доступных функций, позволяющих получить событие на основе идентификатора события.

Ссылка: Функции регистрации событий

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

Это точно так же, как и вы, но более лаконично.

person pyfunc    schedule 27.06.2012
comment
Здорово! Я нашел эту информацию не так давно! Спасибо за ответ, приму, когда смогу. - person Zac Brown; 27.06.2012
comment
Я не знаю, каков был статус на момент публикации этого ответа, но это уже неверно (см. Мой ответ ниже - если вы можете написать запрос WMI, вы можете запросить его). - person Doug R.; 28.10.2015
comment
EventID - целое число. Он никогда не будет соответствовать строке 27035 - person wojtow; 03.07.2017

Я понимаю, что это старый вопрос, но я столкнулся с ним, и если я это сделал, другие тоже могут.

Вы также можете написать собственные запросы, которые позволят вам запрашивать любой из параметров 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()
person Doug R.    schedule 22.05.2014
comment
Подумайте о добавлении фактического кода в свой ответ и отложите ссылки только на ссылки. Вы хотите сделать ответ самодостаточным, поскольку вы не знаете, когда истечет срок действия этих ссылок. - person rayryeng; 23.05.2014
comment
Спасибо за предложение - я пошел дальше и сделал именно это. - person Doug R.; 28.05.2014

Сейчас существует библиотека python (python 3 и выше), которая будет делать то, о чем вы просите, называется winevt. То, что вы ищете, можно сделать с помощью следующего:

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