The reason I’m given that Microsoft has not documented the XML schemas for all the data types is that they are massively complex and simply hard to document. Baelson once told me that "the schema document is this big" holding his hands about 14 inches apart to show the size of the stack of the paper on which the schema document could be printed.
Part of the problem is that different terms are overloaded (such as "Context") and part of it is the way data types are embedded on the fly in other data types. When you map one data type to another using the mapper modules, the original data item is preserved inside an XML tag of the resultant data item. For example, the WMI Event Provider has several lower-level modules under the covers, including a scheduler, a WMI probe, and a mapper module that "converts" the data returned from the WMI probe from PropertyBag data to Event data. Mappers allow you to use values from the source data (WMI-based PropertyBag) in the output datatype. You might use a WMI object property called "LoginName" and use that in your UserName property commonly found in Windows event.
As I mentioned, though, the PropertyBag data is not discarded, it’s embedded.
System.Event.Data represents an event. The schema seems simple. Just some properties you would expect in an event, and their values. There’s no room in here for all the depth of properties you can get from a WMI object.
– <DataItem type="System.Event.Data" time="2008-09-11T11:40:27.6416741-07:00" sourceHealthServiceId="093355C8-0283-EED8-A6BB-393E82B1FA19">
The sticky thing happens when you drill into Trimmed for readability. You see, a whole other data item can go in there, such as an event, or in the case of the XML I am using, a PropertyBag returned by the WMI event provider. The full thing looks like this.
So you see, the System.Event.Data dataitem contains a System.PropertyBag.Data dataitem. The property bag is returned from an event class in the SQL Server namespace. How the heck is anyone supposed to document how to get to a piece of detail data (such as the SPID property) when the propertybag contents are dependent on a WMI class, and therefore the event detail data is dependent on the WMI class?
The <DataItem> tag appears twice in the above XML, but you don’t use it in your XML path in OpsMgr. The first one is always replaced with "$Data/". After that, the path follows the document path identified in BoldBlue in the XML above. To have the SPID number 53 in your alert text, you would use
Notice that the second <DataItem> tag is actually in the path, while the first is not.
What makes it more fun is when you start to use XPathQuery’s for things like rules and monitors. Now you drop the first <DataItem> entirely. The WMI Event Provider module outputs System.Event.Data, so your query in the <XPathQuery> tags would be
No dollar signs. No leading $Data path component.
As another example, Marius blogged about the Application log data type here. In his example, System.ApplicationLog.GenericLogDataEntry was mapped into System.Event.Data. If you were doing the mapping, you could map the "ERROR" property captured from the application text log and stuff it into the ErrorLevel property of the Windows-style Event. You can still get to the original property using
Parameters are generally reliably ordinal, so you can hardcode the ordinal number this way. I ran into a lot of interesting issues with regard to this when I was doing a lot of work with the OleDB data providers.
Getting this data is often difficult. One way to figure out what your datatype looks like is to create a rule on it at a provider level. In other words, create an alert rule that will raise an alert on the source of your data without doing any filtering. To get the WMI PropertyBag example, I created an alert rule that did nothing more than use the namespace
and the very basic WMI query
select * from AUDIT_LOGIN
That created an alert in OpsMgr. The information does show up in relatively friendly display in the alerts view details, but tells nothing about the XPath. From here, it’s off to the database!
The Alerts table contains all alerts, as you might suspect. The Context column contains the dataitem that raised the alert. With that detail, you could start to drill into XPathQuery syntax for filtering, and XPath for parameter replacement in the alert description.
In nearly all cases, there is a Context component of the path when the alert was raised when a monitor changed state. Usually this is in the form of
But in the case of some other things like MonitorTaskDataType, Context is buried a little further down in the path because of the multiple levels of embedding that have happened by the time this datatype is created. See Marius’ note on this for the XML.
Feel free to post questions. I’m interested in getting this article a little more fleshed out.
Update: Useful link to Kevin Holman’s site: http://blogs.technet.com/kevinholman/archive/2007/12/12/adding-custom-information-to-alert-descriptions-and-notifications.aspx