Manually Resetting a Monitor

You may have noticed that all monitors in OpsMgr 2007 have an option called Reset Health.  The problem you may have encountered with this option is that it doesn't do anything on most monitors.  It will typically only work on monitors that were created with a Manual reset.  This option actually does work in all cases, but it's up to the monitor (or more specifically the monitor type) to do something with it.  Most of the monitor types that you're probably building monitors from don't implement the required option for Reset Health to have any effect, so it looks like it just doesn't work.

To understand the issue here, we need to drop down into the management pack XML.  Every monitor is based on a monitor type that may be defined in the same management pack but is more commonly one of the standard monitor types in Microsoft.Windows.Library.  One of the sections of the of the monitor type is RegularDetections that defines what action to take when the different events watched by the monitor type are detected. 

Below is an example from the monitor type Microsoft.Windows.2SingleEventLog2StateMonitorType.  This is the monitor type typically used when you create a monitor using a Windows event for an error state and a second Windows event for a healthy state.  Note the bold section that defines the RegularDetections.  The order of actions to take is defined from the innermost XML node out.  In the case of FirstEventRaised, FirstDataSource is executed to access the event log and then FirstFilterCondition is executed to filter out the event in question.

<UnitMonitorType ID="Microsoft.Windows.2SingleEventLog2StateMonitorType" Accessibility="Public">
  <MonitorTypeStates>
    <MonitorTypeState ID="FirstEventRaised" NoDetection="false" />
    <MonitorTypeState ID="SecondEventRaised" NoDetection="false" />
  </MonitorTypeStates>
  <Configuration>
    <IncludeSchemaTypes>
      <SchemaType>System!System.ExpressionEvaluatorSchema</SchemaType>
    </IncludeSchemaTypes>
    <xsd:element xmlns:xsd="https://www.w3.org/2001/XMLSchema" name="FirstComputerName" type="xsd:string" />
    <xsd:element xmlns:xsd="https://www.w3.org/2001/XMLSchema" name="FirstLogName" type="xsd:string" />
    <xsd:element xmlns:xsd="https://www.w3.org/2001/XMLSchema" name="FirstExpression" type="ExpressionType" />
    <xsd:element xmlns:xsd="https://www.w3.org/2001/XMLSchema" name="SecondComputerName" type="xsd:string" />
    <xsd:element xmlns:xsd="https://www.w3.org/2001/XMLSchema" name="SecondLogName" type="xsd:string" />
    <xsd:element xmlns:xsd="https://www.w3.org/2001/XMLSchema" name="SecondExpression" type="ExpressionType" />
  </Configuration>
  <MonitorImplementation>
    <MemberModules>
      <DataSource ID="FirstDataSource" TypeID="Microsoft.Windows.BaseEventProvider">
        <ComputerName>$Config/FirstComputerName$</ComputerName>
        <LogName>$Config/FirstLogName$</LogName>
      </DataSource>
      <DataSource ID="SecondDataSource" TypeID="Microsoft.Windows.BaseEventProvider">
        <ComputerName>$Config/SecondComputerName$</ComputerName>
        <LogName>$Config/SecondLogName$</LogName>
      </DataSource>
      <ConditionDetection ID="FirstFilterCondition" TypeID="System!System.ExpressionFilter">
        <Expression>$Config/FirstExpression$</Expression>
      </ConditionDetection>
      <ConditionDetection ID="SecondFilterCondition" TypeID="System!System.ExpressionFilter">
        <Expression>$Config/SecondExpression$</Expression>
      </ConditionDetection>
    </MemberModules>
    <RegularDetections>
<RegularDetection MonitorTypeStateID="FirstEventRaised">
<Node ID="FirstFilterCondition">
<Node ID="FirstDataSource" />
</Node>
</RegularDetection>
<RegularDetection MonitorTypeStateID="SecondEventRaised">
<Node ID="SecondFilterCondition">
<Node ID="SecondDataSource" />
</Node>
</RegularDetection>
</RegularDetections>

  </MonitorImplementation>
</UnitMonitorType>

In order to enable the Reset Health option for the monitor, you need to add an OnDemandDetections section to the monitor type to define the action to be taken.  In the case of the Microsoft.Windows.2SingleEventLog2StateMonitorType, we need to decide which event will define success since this is the one we want to execute with the OnDemandDetection.  I'm going to use the first event for an error, and the second event for success.  With that in mind, we can modify the monitor type to the following with the added XML in bold:

<UnitMonitorType ID="Microsoft.Windows.2SingleEventLog2StateMonitorTypeWithReset" Accessibility="Public">
    <MonitorTypeStates>
        <MonitorTypeState ID="FirstEventRaised" NoDetection="false"/>
        <MonitorTypeState ID="SecondEventRaised" NoDetection="false"/>
    </MonitorTypeStates>
    <Configuration>
        <IncludeSchemaTypes>
            <SchemaType>System!System.ExpressionEvaluatorSchema</SchemaType>
        </IncludeSchemaTypes>
        <xsd:element xmlns:xsd="https://www.w3.org/2001/XMLSchema" name="FirstComputerName" type="xsd:string"/>
        <xsd:element xmlns:xsd="https://www.w3.org/2001/XMLSchema" name="FirstLogName" type="xsd:string"/>
        <xsd:element xmlns:xsd="https://www.w3.org/2001/XMLSchema" name="FirstExpression" type="ExpressionType"/>
        <xsd:element xmlns:xsd="https://www.w3.org/2001/XMLSchema" name="SecondComputerName" type="xsd:string"/>
        <xsd:element xmlns:xsd="https://www.w3.org/2001/XMLSchema" name="SecondLogName" type="xsd:string"/>
        <xsd:element xmlns:xsd="https://www.w3.org/2001/XMLSchema" name="SecondExpression" type="ExpressionType"/>
    </Configuration>
    <MonitorImplementation>
        <MemberModules>
            <DataSource ID="FirstDataSource" TypeID="Windows!Microsoft.Windows.BaseEventProvider">
                <ComputerName>$Config/FirstComputerName$</ComputerName>
                <LogName>$Config/FirstLogName$</LogName>
            </DataSource>
            <DataSource ID="SecondDataSource" TypeID="Windows!Microsoft.Windows.BaseEventProvider">
                <ComputerName>$Config/SecondComputerName$</ComputerName>
                <LogName>$Config/SecondLogName$</LogName>
            </DataSource>
            <ProbeAction ID="OnDemandReset" TypeID="System!System.PassThroughProbe"/>
            <ConditionDetection ID="FirstFilterCondition" TypeID="System!System.ExpressionFilter">
                <Expression>$Config/FirstExpression$</Expression>
            </ConditionDetection>
            <ConditionDetection ID="SecondFilterCondition" TypeID="System!System.ExpressionFilter">
                <Expression>$Config/SecondExpression$</Expression>
            </ConditionDetection>
        </MemberModules>
        <RegularDetections>
            <RegularDetection MonitorTypeStateID="FirstEventRaised">
                <Node ID="FirstFilterCondition">
                    <Node ID="FirstDataSource"/>
                </Node>
            </RegularDetection>
            <RegularDetection MonitorTypeStateID="SecondEventRaised">
                <Node ID="SecondFilterCondition">
                    <Node ID="SecondDataSource"/>
                </Node>
            </RegularDetection>
        </RegularDetections>
        <OnDemandDetections>
<OnDemandDetection MonitorTypeStateID="SecondEventRaised">
<Node ID="OnDemandReset"/>
</OnDemandDetection>
</OnDemandDetections>

    </MonitorImplementation>
</UnitMonitorType>

Note that there are two nodes added to the XML.  First, we need to add a new System.PassThroughProbe module so the monitor knows to even look for our reset.  We next need an OnDemandDetections node that specifies what MonitorTypeStateID to set when the reset is performed.  In this case, I'm assuming that the second event indicates a healthy state.  The MonitorTypeStateID of SecondEventRaised directly corresponds to the same ID in the MonitorTypeStates node.