Reputation: 131
I am writing an XPath query string to select records from the Windows Event Log where the Event source contains a particular string. I have a version which performs an exact match where the Path element of the query is
Path='Application'>*[System[Provider[@Name='MyApp']
This works fine, but I want to find all events where the source contains 'MyApp'
. I have read various articles and I think it should be
Path='Application'>*[System[Provider[contains(@Name, 'MyApp']
but this fails with an 'Invalid Query'
error.
Any idea what I am doing wrong?
Update:
I edited my query in line with the fix below and my full query string is now:
var Query = @"<QueryList><Query Id='0' Path='Application'>
<Select Path='Application'>*[System[Provider[contains(@Name, 'MyApp')] and (Level=2 or Level=3)]]</Select>
</Query></QueryList>";
var EventLogQuery = new EventLogQuery("Application", PathType.LogName, Query);
but this still fails. If I change the query to be
var Query = @"<QueryList><Query Id='0' Path='Application'>
<Select Path='Application'>*[System[Provider[@Name='MyApp'] and (Level=2 or Level=3)]]</Select>
</Query></QueryList>";
it all works.
Does the EventLogQuery support 'contains'. This article How to select for content contains substring in Windows Event Viewer using XPath 1.0? suggests it does not.
Upvotes: 1
Views: 116
Reputation: 111716
Your posted XPath is missing a closing )
for contains()
and closing predicate ]
for several levels:
*[System[Provider[contains(@Name, 'MyApp']
should be
*[System[Provider[contains(@Name, 'MyApp')]]]
More conventionally, for a top-level Event
element this would be written
/Event[System/Provider[contains(@Name, 'MyApp')]]
Take into account the namespaces typically involved. Given the following sample Windows Event Log XML,
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Microsoft-Windows-Security-Auditing"
Guid="{12345678-1234-1234-1234-123456789012}" />
</System>
</Event>
by declaring a namespace prefix,
e = "http://schemas.microsoft.com/win/2004/08/events/event"
and using it in your XPath,
/e:Event[e:System/e:Provider[contains(@Name, 'MyApp')]]
See How does XPath deal with XML namespaces? for how to declare and use (or defeat if necessary) namespaces in XPath.
The above assumes that you're using a full, compliant XPath processor/library. Apparently Windows Event Log is not (thanks to the link provided by @JamesCockayne, +1):
Windows Event Log supports a subset of XPath 1.0. For details on the limitations, see XPath 1.0 limitations.
In general, it's better to use a fully compliant XPath processor/library.
Upvotes: 1
Reputation: 138
I think the issue is that the contains
function is missing a closing parentheses. I also think we are missing some closing square braces. I'm not sure how your first example works.
Try *[System[Provider[contains(@Name, 'MyApp')]]]
This guide seems to have many good examples that you should be able to modify to meet your needs https://learn.microsoft.com/en-us/windows/win32/wes/consuming-events
Upvotes: 1