Joel Christophel
Joel Christophel

Reputation: 2663

Windows Task Scheduler XPath for filtering event on hour of day

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

Answers (1)

LMC
LMC

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

Related Questions