Reputation: 2663
I'm creating a custom event filter in order to trigger a task from Windows Task Scheduler. I'm needing to select my event only if it occurs before x
o'clock.
Here's the portion of the event XML that I care about:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="acvpnagent" />
<EventID Qualifiers="25600">2039</EventID>
<TimeCreated SystemTime="2021-11-01T04:24:49.6333217Z" />
<Channel>Cisco AnyConnect Secure Mobility Client</Channel>
</System>
</Event>
So far I have the following XPath, but it is missing the time constraint:
<QueryList>
<Query Id="0" Path="Cisco AnyConnect Secure Mobility Client">
<Select Path="Cisco AnyConnect Secure Mobility Client">*[System[Provider[@Name='acvpnagent'] and (EventID=2039)</Select>
</Query>
</QueryList>
Is it possible to add a condition for TimeCreated
to satisfy my constraint? And am I still limited to XPath 1.0 on Windows 10?
Upvotes: 0
Views: 335
Reputation: 12662
This XPath 1.0 expression will select Event
nodes as follows
//x:Event[./x:System/x:Provider/@Name="acvpnagent" and ./x:System/x:EventID=2039 and number(translate(substring-before(substring-after(./x:System/x:TimeCreated/@SystemTime,"T"),"."),":","")) < 110000]
This XPath will select nodes according to the criteria in the OP's sample
//x:Event[./x:System/x:Provider/@Name="acvpnagent" and ./x:System/x:EventID=2039]
While this XPath part will add a filter by time of day
number(translate(substring-before(substring-after(./x:System/x:TimeCreated/@SystemTime,"T"),"."),":","")) < 110000
Date handling
Given an ISO-8601
date as 2021-11-01T04:24:49.6333217Z
, this would return the HH:mm:ss part
substring-before(substring-after(./x:System/x:TimeCreated/@SystemTime,"T"),".")
Result: 04:24:49
Let's remove semicolons:
translate(substring-before(substring-after(./x:System/x:TimeCreated/@SystemTime,"T"),"."),":","")
Result: 042449
Finally, make it a number and compare with desired limit
number(translate(substring-before(substring-after(./x:System/x:TimeCreated/@SystemTime,"T"),"."),":","")) < 110000
Given this XML sample
<root>
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="acvpnagent" />
<EventID Qualifiers="25600">2039</EventID>
<TimeCreated SystemTime="2021-11-01T04:24:49.6333217Z" />
<Channel>Cisco AnyConnect Secure Mobility Client</Channel>
</System>
</Event>
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="acvpnagent" />
<EventID Qualifiers="25600">2039</EventID>
<TimeCreated SystemTime="2021-11-01T08:24:49.6333217Z" />
<Channel>Cisco AnyConnect Secure Mobility Client</Channel>
</System>
</Event>
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="acvpnagent" />
<EventID Qualifiers="25600">2039</EventID>
<TimeCreated SystemTime="2021-11-01T11:24:49.6333217Z" />
<Channel>Cisco AnyConnect Secure Mobility Client</Channel>
</System>
</Event>
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="acvpnagent" />
<EventID Qualifiers="25600">2039</EventID>
<TimeCreated SystemTime="2021-11-01T22:24:49.6333217Z" />
<Channel>Cisco AnyConnect Secure Mobility Client</Channel>
</System>
</Event>
</root>
Find events that match the criteria and occured before 11:00:00 using this XPath
//x:Event[./x:System/x:Provider/@Name="acvpnagent" and ./x:System/x:EventID=2039 and number(translate(substring-before(substring-after(./x:System/x:TimeCreated/@SystemTime,"T"),"."),":","")) < 110000]
Result:
echo -e 'setns x=http://schemas.microsoft.com/win/2004/08/events/event\ncat //x:Event[./x:System/x:Provider/@Name="acvpnagent" and ./x:System/x:EventID=2039 and number(translate(substring-before(substring-after(./x:System/x:TimeCreated/@SystemTime,"T"),"."),":","")) < 110000]' | xmllint --shell tmp.xml
/ > setns x=http://schemas.microsoft.com/win/2004/08/events/event
/ > cat //x:Event[./x:System/x:Provider/@Name="acvpnagent" and ./x:System/x:EventID=2039 and number(translate(substring-before(substring-after(./x:System/x:TimeCreated/@SystemTime,"T"),"."),":","")) < 110000]
-------
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="acvpnagent"/>
<EventID Qualifiers="25600">2039</EventID>
<TimeCreated SystemTime="2021-11-01T04:24:49.6333217Z"/>
<Channel>Cisco AnyConnect Secure Mobility Client</Channel>
</System>
</Event>
-------
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="acvpnagent"/>
<EventID Qualifiers="25600">2039</EventID>
<TimeCreated SystemTime="2021-11-01T08:24:49.6333217Z"/>
<Channel>Cisco AnyConnect Secure Mobility Client</Channel>
</System>
</Event>
/ >
If a full date is used for comparison, this would be the XPath expression
//x:Event[./x:System/x:Provider/@Name="acvpnagent" and ./x:System/x:EventID=2039 and number(translate(substring-before(./x:System/x:TimeCreated/@SystemTime,"."),"T:-","")) < 20211101110000]
Note 1: expressions start with ./
to make evaluation in the current node context.
Note 2: I don't have Windows to test but XPath 1.0 is mostly independent of the language/OS so it should work. The OP would need to add namespace handling to his implementation or remove the x:
namespace prefix from expressions in this answer.
Upvotes: 1