If you have come across articles how to extract event data in an event driven task (like this and this) and you want to pass this data as argument(s) to the script or program assigned to this task, you could have probably tried to parse more than a single named value as well. In such case this article is for you: it doesn’t provide a workaround, but guesses why it can’t be done. The benefit is that you won’t lose two days of trial and error, like I did 🙂
OK, after finding out how retrieval of single values can be done in the usual XPath conform way such as:
Event/System/EventID | for the value of the EventID element
Event/System/Provider/@Name | for the value of the Name attribute of the Provider element
And
Event/EventData/Data[@Name="SomeValue"] | for the value of the Data element that has an attribute Name that has a SomeValue value
I thought that it is a peanut to grab more input, respectively more generic values, because you often have events without named instances of EventData (such as the DFSR events), or events with unpredictable structure like this DNS event:
<EventData Name="DNS_EVENT_DS_INTERFACE_ERROR">
<Data Name="param1" />
<Binary>51000000</Binary>
</EventData>
The first thought is to catch the whole EventData element including child elements using the Event/EventData query, but since it didn’t work I tried to get ‘only’ all the child elements, using Event/EventData/* query as described here.
Since both upper attempts failed I was misled to think that there is something wrong with the parsing and spent a whole day in experimenting and tracking results, eventually learning a lot about PowerShell’s two parsing modes and the "–%" (no parsing) symbol. But this didn’t help a lot. Here some examples of what I tried, assuming I provided <Value name="EventData">Event/EventData/*<Value> in the XML configuration and expected either a string or array of strings with all child items:
-Command "C:\scripts\Test.ps1" ‘$(EventData)’
ditto "$(EventData)"
ditto "$(EventData)
"
ditto ‘$(EventData.ToString())’
ditto ‘@(EventData)’
To no avail…
I checked here for the properties of EventTrigger.ValueQueries. And I double-checked the spare ExecAction.Arguments information. It was at this moment when I started doubting at the implementation of the XPath rules, because both sites were showing the properties "As String".
First I tried the collective XPath queries expecting a set of all hits:
Event/EventData
Event/EventData/*
Event/EventData/Data
And later I checked for single values, i.e. scalars, referenced by position, as single warriors like this had tried before, not really expecting any positive outcomes any more 🙁
Event/EventData/Data[1]
Event/EventData/Data[position()=1]
Event/EventData/Data[last()]
In all those cases a warning including the following information was generated: "Ensure all the task triggers are valid as configured. Additional Data: Error Value: 2147942487". This behavior was reported already in 2011 but failed to be fixed, needless to say. What caught my eye though was techie’s reply: "Error code 2147942667 indicates that the directory name is invalid". Well, since we are sure that we are not querying any directory what could THIS error mean? Then it struck me down by surprise: could it be the XPath query itself? Could it be that Taskschd.dll is parsing the XML parameters in such a prohibitive way, that it only accepts single named hits? I am still not 100% sure about that, but this is the closest explanation of the phenomenon.
Just to make sure what I was on the right direction, I tried the following:
Event/EventData/Data[@Name="TargetUserName"] | this worked as expected
Event/EventData/Data[@Name !="TargetUserName"] | didn’t work
Event/EventData/Data[@Name !="Dummy Attribute"] | didn’t work
Event/EventData/Data[. != "Dummy Value"] | didn’t work
For the ones that didn’t work, the same warning message with error 2147942487 was created, so at this point I knew two things:
- Some algorithm in the code is preventing me from utilizing the complete XPath expression set
- Most probably the same algorithm takes care that I never get a whole set of results returned under one variable
- Even worse: I cannot even reference single values if they are unnamed, i.e. by position, be it index[#] or method last()
Whereas I can agree with the design consideration to return values as strings (although array of strings is quite commonly used to pass arrays or hashtables to shell or script languages, see here for an example), a definitely disagree with the castration of the XPath query opportunities – this is mean, misleading and unreasonable, especially in the case of the position query, and secondly what is the problem of returning more than one values, be it comma, tab or newline separated, as a string?
After all this research I can only conclude that I cannot rely on Microsoft’s own references and have to reverse engineer every system error. Thanks a lot for that: that makes a damn good software engineer out of me!
Keywords: EventData, XPath, XML, Reference Event Data, Parsing Modes, Scheduled Task, ValueQueries, EventTrigger, ExecAction,
Reference:
http://michlstechblog.info/blog/windows-passing-parameters-to-event-triggered-schedule-tasks/
http://aymanstechblog.blogspot.de/2012/05/passing-event-details-as-arguments.html
http://stackoverflow.com/questions/20055435/variable-substitution-issue-while-passing-event-details-to-scheduled-task
http://msdn.microsoft.com/en-us/library/ms256086(v=vs.110).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa446885(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa446891(v=vs.85).aspx
http://social.msdn.microsoft.com/Forums/en-US/245bff01-4a7d-420a-9e06-b8872c3aca9c/reference-event-log-data-by-position-using-xpath?forum=xmlandnetfx
http://social.technet.microsoft.com/Forums/windowsserver/en-US/ab9293a7-7c4f-4584-9116-8c21881fd6b7/error-adding-valuequeries-to-scheduled-task?forum=winserverManagement
http://rkeithhill.wordpress.com/2007/11/24/effective-powershell-item-10-understanding-powershell-parsing-modes/
http://technet.microsoft.com/en-us/library/hh847892.aspx
http://stackoverflow.com/questions/8720990/background-job-in-powershell
Thanks for posting this! I’ve just spent a couple of hours on the very same issue. This will save me spending the rest of the evening going mad 🙂