Bug in SCOM’s DayTimeExpression operator of System.ExpressionFilter

Matthew Long’s post on the useful DayTimeExpression module of the System.ExpressionFilter data filter is the only useful information I could find on its use, save for the MSDN documentation. However, in using the module, I’ve noticed what appears to be a bug in its implementation.

The problem

The module works by checking whether a date-time is bound (or not bound, as defined by <InRange />) by a window that’s defined by (a) a days of the week mask and (b) a time window, the start and end of which are specified by the number of seconds since midnight. The problem appears to be that the date-time is interpreted as local time, despite being defined in ISO 8601 format, e.g. 2015-05-29T17:15:00Z, rather than being correctly interpreted as UTC and converted to local time before being checked against the defined window. This problem occurs whether a date-time is manually specified, e.g. <Value Type="DateTime">2015-05-29T17:15:00Z</Value>, or is obtained at runtime, e.g. <XPathQuery Type="DateTime">./@time</XPathQuery>.

The workaround

It may be possible to solve this problem using XQuery/XPath, but my solution is to return the current local date-time from the PowerShell script called by the data source, albeit presented as UTC in ISO 8601 format. For example, if the script were executed at 17:15 (local time), the script would return, in its property bag, a property with a value of 2015-05-29T17:15:00Z. This is a hack, as, because I’m on BST (UTC+1), this value should be 2015-05-29T16:15:00Z, but this triggers the bug.

In my PowerShell script:

$Bag.AddValue("Date-time executed (local time)", (Get-Date).ToString("yyyy-MM-ddTHH:mm:ssZ"))

In my monitor type:

<Expression>
	<DayTimeExpression>
		<ValueExpression>
			<XPathQuery Type="DateTime">Property[@Name='Date-time executed (local time)']</XPathQuery>
		</ValueExpression>
		<StartTime>$Config/SecondsFromMidnightCheckWindowStart$</StartTime>
		<EndTime>$Config/SecondsFromMidnightCheckWindowEnd$</EndTime>
		<Days>$Config/DaysOfWeekMask$</Days>
		<InRange>true</InRange>
	</DayTimeExpression>
</Expression>

I am now able to define the window using the number of seconds from midnight, local time, and System.ExpressionFilter correctly checks this window against the execution time.