Monitoring Object Properties

I really hate to reinvent the wheel.  I have had the need to create monitors for values that are already discovered as object properties.  For example: the owner of a SQL database, the DHCP settings of a network adapter, or the log file directory of a web site.

The first option that I though of was to create a script based monitor that took the object property as an argument and evaluated it.  But it seemed like a needless burden on the agent to spawn an instance of CScript.exe just to compare some strings.

It seemed to me that this should be something the agent could do internally, without needing to create child processes just to run scripts.  However neither the Authoring Console nor the Operations Console offer a monitor type to do this.

It turns out that making your own monitor type is actually quite simple, but you need to have a very good understanding of how a SCOM MP handles XML and XPATH queries.

You do not need to make any custom modules.  The only modules you need are System.SimpleScheduler and System.ExpressionFilter.  You will need to do a little hand editing of the System.ExpressionFilter configuration, or your agents will throw lots of "Expression Filter Module Failed Initialization" alerts.

Here's what I did.

1.) Create a new Composite Monitor Type.

2.) Add two String Configuration Elements

 

3.) Set the Operational States

 

4.) We need a data source.  I usually use System.SimpleScheduler

5.) Add two Condition Detections.  One for the strings being equal, and one for the strings not being equal.

 

Now here's the tricky part!  The default configuration for the module will include an XPATH query.  This will not work!

  <Expression>
    <SimpleExpression>
      <ValueExpression>
        <XPathQuery Type="String">$Config/StringOne$</XPathQuery>
      </ValueExpression>
      <Operator>Equal</Operator>
      <ValueExpression>
        <Value Type="String">$Config/StringTwo$</Value>
      </ValueExpression>
    </SimpleExpression>
  </Expression>

You will need to hand edit it to use two Value Expressions.  Change it to this:

   <Expression>
    <SimpleExpression>
      <ValueExpression>
        <Value Type="String">$Config/StringOne$</Value>
      </ValueExpression>
      <Operator>Equal</Operator>
      <ValueExpression>
        <Value Type="String">$Config/StringTwo$</Value>
      </ValueExpression>
    </SimpleExpression>
  </Expression>

And the same thing for the not equal condition detection:

  <Expression>
    <SimpleExpression>
      <ValueExpression>
        <Value Type="String">$Config/StringOne$</Value>
      </ValueExpression>
      <Operator>NotEqual</Operator>
      <ValueExpression>
        <Value Type="String">$Config/StringTwo$</Value>
      </ValueExpression>
    </SimpleExpression>
  </Expression>

6.)  Set the regular composition, and your monitor type is ready.

Your monitor type is now ready to use.  If you want to reference it from other management packs, be sure to make it public and put it in a sealed management pack.

Here's a unit monitor that targets Microsoft.SQLServer.Database to see if the database is owned by the "sa" account.

You can use variants of this for Substring Contains, Substring Does Not Contain, wildcards, regular expressions, or whatever else you need.  The ones below are handy for making sure that a web site is not logging to a path that contains "C:\"

  <Expression>
    <RegExExpression>
      <ValueExpression>
        <Value Type="String">$Config/StringSearchedIn$</Value>
      </ValueExpression>
      <Operator>ContainsSubstring</Operator>
      <Pattern>$Config/StringSearchedFor$</Pattern>
    </RegExExpression>
  </Expression>

  <Expression>
    <RegExExpression>
      <ValueExpression>
        <Value Type="String">$Config/StringSearchedIn$</Value>
      </ValueExpression>
      <Operator>DoesNotContainSubstring</Operator>
      <Pattern>$Config/StringSearchedFor$</Pattern>
    </RegExExpression>
  </Expression>