How to Query for an Event Log Details with a Given Event Id

How to Query for an event log details with a given event id?

There are a few new twists if your going to query events from the new style Windows EventLogs.

  1. You will have to use the classes from the System.Diagnostics.Eventing.Reader namespace to read the new events.
  2. Your query will be in Xpath form, so that time value is tricky, see msdn for the EventLogQuery definition.
  3. Your program will run into access issues, be ready to impersonate a user that's included in the EventReaders AD group on the logging machine.

This sample shows some of the new access methods:

string eventID = "5312";
string LogSource = "Microsoft-Windows-GroupPolicy/Operational";
string sQuery = "*[System/EventID=" + eventID + "]";

var elQuery = new EventLogQuery(LogSource, PathType.LogName, sQuery);
using (var elReader = new System.Diagnostics.Eventing.Reader.EventLogReader(elQuery))
{

List<EventRecord> eventList = new List<EventRecord>();
EventRecord eventInstance = elReader.ReadEvent();
try
{
for (null != eventInstance; eventInstance = elReader.ReadEvent())
{
//Access event properties here:
//eventInstance.LogName;
//eventInstance.ProviderName;
eventList.Add(eventInstance);
}
}
finally
{
if (eventInstance != null)
eventInstance.Dispose();
}
}

How can I query the event log for a specific source using xpath?

Change the query string something like that (you may want to create a text resource and put this query in it to avoid escapes):

*[System[Provider[@Name='Microsoft-Windows-ADSI' or @Name='Outlook'] and (EventID=1 or EventID=2 or EventID=3)]]

The above is equivalent to:

(EventID in (1,2,3)) and (Source in ('Microsoft-Windows-ADSI', 'Outlook'))

Getting details of an event from Event Log

Upon looking at your code, here's a quick summary of what I would do:

Remove ProgressChanged handler. It is intended for reporting current status to user, which you don't do. Instead, call Items.Add in DoWork handler.

Create EventLog once. This just seems nicer and saves you from potentially creating it in a loop if you aren't careful.

Instead of parsing text with regex, create a special class. This is really important and will save you a lot of pain when you need more accurate behavior or don't wish to display index at all. Regular expressions are slow, and data intended for display to user must never be parsed. You must use classes.

Use meaningful names. I know that you didn't clean up the code, but if you want someone to help you over the internet, you really should.

Finally, get item by index. If you looked into the documentation, you would have noticed there's an indexer property that gets item directly by its index.

class EntryItem {
public EntryItem (EventLogEntry entry)
{
EntryIndex = entry.Index;
ItemText = string.Format ("{0} - {1} - {2} - {3}",
entry.Index,
entry.EntryType,
entry.TimeWritten,
entry.Source);
}

public string ItemText { get; private set; }
public int EntryIndex { get; private set; }

public override string ToString ()
{
return ItemText;
}
}

private EventLog log = new EventLog {
Log = "System"
};

private void eventLoader_DoWork (object sender, DoWorkEventArgs e)
{
foreach (EventLogEntry entry in this.log.Entries)
this.Dispatcher.BeginInvoke (() => eventListBox.Items.Add (new EntryItem (entry)));
}

private void eventListBox_SelectionChanged (object sender, SelectionChangedEventArgs e)
{
EntryItem item = eventListBox.SelectedItem as EntryItem;
if (item == null)
return;

var entry = log.Entries [item.EntryIndex];
currentEntryLabel.Content = entry.Message;
}

Query Process ID (PID) from Windows Event Log

Never use Format-* cmdlets when further processing of your data is intended. What you want to do is expand the Message property and adjust your pattern, so that you extract the actual PID instead of the entire line. You also don't want to use a simple match here.

... |
Select-Object -Expand Message |
Select-String -Pattern '(?<=process id:\s+)\d+' |
Select-Object -Expand Matches |
Select-Object -Expand Value

($<=...) is a so-called positive lookbehind assertion that allows you to match something in your string without including that in the match that is returned. Essentially the pattern means "match \d+ only if it's preceded by that other string".

Read Specific Windows Event Log Event

No! There are no functions available which allows you to obtain the event based on event id.

Reference: 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.

Only other method of interest is reading the oldest event.

You will have to iterate through the results any way and your approach is correct :)

You can only change the form of your approach like below but this is unnecessary.

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

This is just the same way as you are doing but more succinct



Related Topics



Leave a reply



Submit