<ManagementPack ContentReadable="true" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <Manifest>
    <Identity>
      <ID>MPAuthor.RegistryMonitor</ID>
      <Version>1.0.0.2</Version>
    </Identity>
    <Name>MPAuthor.RegistryMonitor</Name>
    <References>
      <Reference Alias="SC">
        <ID>Microsoft.SystemCenter.Library</ID>
        <Version>6.1.7221.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="Windows">
        <ID>Microsoft.Windows.Library</ID>
        <Version>6.1.7221.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="Health">
        <ID>System.Health.Library</ID>
        <Version>6.1.7221.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="System">
        <ID>System.Library</ID>
        <Version>6.1.7221.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
    </References>
  </Manifest>
  <TypeDefinitions>
    <EntityTypes>
      <ClassTypes>
        <ClassType ID="MPAuthor.RegistryMonitor.TargetClass" Accessibility="Internal" Abstract="false" Base="Windows!Microsoft.Windows.ComputerRole" Hosted="true" Singleton="false" />
      </ClassTypes>
    </EntityTypes>
    <ModuleTypes>
      <ProbeActionModuleType ID="MPAuthor.RegistryMonitor.Probe.FileInfo" Accessibility="Internal" Batching="false" PassThrough="false">
        <Configuration>
          <xsd:element minOccurs="1" name="FileName" type="xsd:string" />
        </Configuration>
        <ModuleImplementation Isolation="Any">
          <Composite>
            <MemberModules>
              <ProbeAction ID="Script" TypeID="Windows!Microsoft.Windows.PowerShellPropertyBagTriggerOnlyProbe">
                <ScriptName>FileInfo.ps1</ScriptName>
                <ScriptBody><![CDATA[
param($fileName)

$file = get-item -path $fileName

$MinutesSinceUpdate = (new-timespan -start $file.LastWriteTime -end (get-date)).totalMinutes

$api = new-object -comObject 'MOM.ScriptAPI'
$bag = $api.CreatePropertyBag()
$bag.AddValue('FileName',$file.Name)
$bag.AddValue('FileSize',$file.Length)
$bag.AddValue('MinutesSinceUpdate',(new-timespan -start $file.LastWriteTime -end (get-date)).totalMinutes)
$bag.AddValue('MinutesSinceCreation',(new-timespan -start $file.CreationTime -end (get-date)).totalMinutes)

$api.Return($bag)
$bag
  ]]></ScriptBody>
                <Parameters>
                  <Parameter>
                    <Name>fileName</Name>
                    <Value>$Config/FileName$</Value>
                  </Parameter>
                </Parameters>
                <TimeoutSeconds>30</TimeoutSeconds>
              </ProbeAction>
            </MemberModules>
            <Composition>
              <Node ID="Script" />
            </Composition>
          </Composite>
        </ModuleImplementation>
        <OutputType>System!System.PropertyBagData</OutputType>
        <TriggerOnly>true</TriggerOnly>
      </ProbeActionModuleType>
    </ModuleTypes>
    <MonitorTypes>
      <UnitMonitorType ID="MPAuthor.RegistryMonitor.MonitorType.RegistryValue" Accessibility="Public">
        <MonitorTypeStates>
          <MonitorTypeState ID="Match" NoDetection="false" />
          <MonitorTypeState ID="NoMatch" NoDetection="false" />
        </MonitorTypeStates>
        <Configuration>
          <xsd:element minOccurs="1" name="IntervalSeconds" type="xsd:integer" />
          <xsd:element minOccurs="0" name="SyncTime" type="xsd:string" />
          <xsd:element minOccurs="1" name="ComputerName" type="xsd:string" />
          <xsd:element minOccurs="1" name="RegPath" type="xsd:string" />
          <xsd:element minOccurs="1" name="DesiredRegValue" type="xsd:string" />
        </Configuration>
        <OverrideableParameters>
          <OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int" />
          <OverrideableParameter ID="SyncTime" Selector="$Config/SyncTime$" ParameterType="string" />
          <OverrideableParameter ID="DesiredRegValue" Selector="$Config/DesiredRegValue$" ParameterType="string" />
        </OverrideableParameters>
        <MonitorImplementation>
          <MemberModules>
            <DataSource ID="Scheduler" TypeID="System!System.SimpleScheduler">
              <IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
              <SyncTime>$Config/SyncTime$</SyncTime>
            </DataSource>
            <ProbeAction ID="RegProbe" TypeID="Windows!Microsoft.Windows.RegistryProbe">
              <ComputerName>$Config/ComputerName$</ComputerName>
              <RegistryAttributeDefinitions>
                <RegistryAttributeDefinition>
                  <AttributeName>RegValue</AttributeName>
                  <Path>$Config/RegPath$</Path>
                  <PathType>1</PathType>
                  <AttributeType>1</AttributeType>
                </RegistryAttributeDefinition>
              </RegistryAttributeDefinitions>
            </ProbeAction>
            <ProbeAction ID="PassThrough" TypeID="System!System.PassThroughProbe" />
            <ConditionDetection ID="FilterMatch" TypeID="System!System.ExpressionFilter">
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <XPathQuery Type="String">Values/RegValue</XPathQuery>
                  </ValueExpression>
                  <Operator>Equal</Operator>
                  <ValueExpression>
                    <Value Type="String">$Config/DesiredRegValue$</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
            </ConditionDetection>
            <ConditionDetection ID="FilterNoMatch" TypeID="System!System.ExpressionFilter">
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <XPathQuery Type="String">Values/RegValue</XPathQuery>
                  </ValueExpression>
                  <Operator>NotEqual</Operator>
                  <ValueExpression>
                    <Value Type="String">$Config/DesiredRegValue$</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
            </ConditionDetection>
          </MemberModules>
          <RegularDetections>
            <RegularDetection MonitorTypeStateID="Match">
              <Node ID="FilterMatch">
                <Node ID="RegProbe">
                  <Node ID="Scheduler" />
                </Node>
              </Node>
            </RegularDetection>
            <RegularDetection MonitorTypeStateID="NoMatch">
              <Node ID="FilterNoMatch">
                <Node ID="RegProbe">
                  <Node ID="Scheduler" />
                </Node>
              </Node>
            </RegularDetection>
          </RegularDetections>
          <OnDemandDetections>
            <OnDemandDetection MonitorTypeStateID="Match">
              <Node ID="FilterMatch">
                <Node ID="RegProbe">
                  <Node ID="PassThrough" />
                </Node>
              </Node>
            </OnDemandDetection>
            <OnDemandDetection MonitorTypeStateID="NoMatch">
              <Node ID="FilterNoMatch">
                <Node ID="RegProbe">
                  <Node ID="PassThrough" />
                </Node>
              </Node>
            </OnDemandDetection>
          </OnDemandDetections>
        </MonitorImplementation>
      </UnitMonitorType>
    </MonitorTypes>
  </TypeDefinitions>
  <Monitoring>
    <Discoveries>
      <Discovery ID="MPAuthor.RegistryMonitor.Discovery.TargetClass" Enabled="true" Target="Windows!Microsoft.Windows.OperatingSystem" ConfirmDelivery="false" Remotable="true" Priority="Normal">
        <Category>Discovery</Category>
        <DiscoveryTypes>
          <DiscoveryClass TypeID="MPAuthor.RegistryMonitor.TargetClass" />
        </DiscoveryTypes>
        <DataSource ID="DS" TypeID="Windows!Microsoft.Windows.FilteredRegistryDiscoveryProvider">
          <ComputerName>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$</ComputerName>
          <RegistryAttributeDefinitions>
            <RegistryAttributeDefinition>
              <AttributeName>AppExists</AttributeName>
              <Path>SOFTWARE\MPAuthor\PropertyBag</Path>
              <PathType>0</PathType>
              <AttributeType>0</AttributeType>
            </RegistryAttributeDefinition>
          </RegistryAttributeDefinitions>
          <Frequency>3600</Frequency>
          <ClassId>$MPElement[Name="MPAuthor.RegistryMonitor.TargetClass"]$</ClassId>
          <InstanceSettings>
            <Settings>
              <Setting>
                <Name>$MPElement[Name="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Name>
                <Value>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Value>
              </Setting>
              <Setting>
                <Name>$MPElement[Name="System!System.Entity"]/DisplayName$</Name>
                <Value>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Value>
              </Setting>
            </Settings>
          </InstanceSettings>
          <Expression>
            <SimpleExpression>
              <ValueExpression>
                <XPathQuery Type="String">Values/AppExists</XPathQuery>
              </ValueExpression>
              <Operator>Equal</Operator>
              <ValueExpression>
                <Value Type="String">True</Value>
              </ValueExpression>
            </SimpleExpression>
          </Expression>
        </DataSource>
      </Discovery>
    </Discoveries>
    <Monitors>
      <UnitMonitor ID="MPAuthor.RegistryMonitor.Monitor.RegValue" Accessibility="Internal" Enabled="true" Target="MPAuthor.RegistryMonitor.TargetClass" ParentMonitorID="Health!System.Health.ConfigurationState" Remotable="true" Priority="Normal" TypeID="MPAuthor.RegistryMonitor.MonitorType.RegistryValue" ConfirmDelivery="true">
        <Category>Custom</Category>
        <OperationalStates>
          <OperationalState ID="UIGeneratedOpStateId78d71e4bf9304a019d725b4c05534dbc" MonitorTypeStateID="Match" HealthState="Success" />
          <OperationalState ID="UIGeneratedOpStateIdf109ba2dbbd9457c83218aa39102f7d1" MonitorTypeStateID="NoMatch" HealthState="Error" />
        </OperationalStates>
        <Configuration>
          <IntervalSeconds>120</IntervalSeconds>
          <ComputerName>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</ComputerName>
          <RegPath>SOFTWARE\MPAuthor\RegistryMonitor\TestValue</RegPath>
          <DesiredRegValue>ThisValue</DesiredRegValue>
        </Configuration>
      </UnitMonitor>
    </Monitors>
  </Monitoring>
  <Presentation>
    <Views>
      <View ID="MPAuthor.RegistryMonitor.View.TargetClass" Accessibility="Internal" Enabled="true" Target="MPAuthor.RegistryMonitor.TargetClass" TypeID="SC!Microsoft.SystemCenter.StateViewType" Visible="true">
        <Category>StateCollection</Category>
        <Criteria />
      </View>
    </Views>
    <Folders>
      <Folder ID="MPAuthor.RegistryMonitor.Folder" Accessibility="Internal" ParentFolder="SC!Microsoft.SystemCenter.Monitoring.ViewFolder.Root" />
    </Folders>
    <FolderItems>
      <FolderItem ElementID="MPAuthor.RegistryMonitor.View.TargetClass" Folder="MPAuthor.RegistryMonitor.Folder" />
    </FolderItems>
    <StringResources>
      <StringResource ID="AlertMessageID3c3f53bd716449f58e793397c3a79f5b" />
      <StringResource ID="MPAuthor.RegistryMonitor.Monitor.FileSize_AlertMessageResourceID" />
      <StringResource ID="MPAuthor.RegistryMonitor.SimpleEventAlert.AlertMessage" />
    </StringResources>
  </Presentation>
  <LanguagePacks>
    <LanguagePack ID="ENU" IsDefault="true">
      <DisplayStrings>
        <DisplayString ElementID="MPAuthor.RegistryMonitor">
          <Name>MPAuthor Sample - Property Bag</Name>
          <Description>This management pack provides an example of a monitor based on a registry value.  A monitor type is included that will periodically check a specified registry value and compare it to a desired value.  The monitor provides the path to the value, the duration to check, and the value to compare it to.

The included monitor checks the value at HKLM\SOFTWARE\MPAuthor\RegistryMonitor\TestValue and sets the monitor to a critical state if the value is not "ThisValue".  A different registry value and desired value can be used by changing the configuration of the monitor.

All rules and monitors are targeted at a class called MPAuthor.RegistryMonitor.Target.  This is discovered by creating a registry key at HKLM\SOFTWARE\MPAuthor\RegisterMonitor. This registry key must be on the same agent with the registry value being checked.</Description>
        </DisplayString>
        <DisplayString ElementID="MPAuthor.RegistryMonitor.Discovery.TargetClass">
          <Name>MPAuthor Discover PropertyBag Target Class</Name>
        </DisplayString>
        <DisplayString ElementID="MPAuthor.RegistryMonitor.Folder">
          <Name>MPAuthor Sample Registry Monitor</Name>
          <Description />
        </DisplayString>
        <DisplayString ElementID="MPAuthor.RegistryMonitor.Monitor.FileSize_AlertMessageResourceID">
          <Name>File size</Name>
          <Description>Please see the alert context for details.</Description>
        </DisplayString>
        <DisplayString ElementID="MPAuthor.RegistryMonitor.Monitor.RegValue">
          <Name>Reg Value</Name>
          <Description />
        </DisplayString>
        <DisplayString ElementID="MPAuthor.RegistryMonitor.Monitor.RegValue" SubElementID="UIGeneratedOpStateId78d71e4bf9304a019d725b4c05534dbc">
          <Name>Match</Name>
        </DisplayString>
        <DisplayString ElementID="MPAuthor.RegistryMonitor.Monitor.RegValue" SubElementID="UIGeneratedOpStateIdf109ba2dbbd9457c83218aa39102f7d1">
          <Name>NoMatch</Name>
        </DisplayString>
        <DisplayString ElementID="MPAuthor.RegistryMonitor.MonitorType.RegistryValue">
          <Name>Registry Value Monitor Type</Name>
          <Description />
        </DisplayString>
        <DisplayString ElementID="MPAuthor.RegistryMonitor.Probe.FileInfo">
          <Name>MPAuthor File Info Probe Action</Name>
        </DisplayString>
        <DisplayString ElementID="MPAuthor.RegistryMonitor.TargetClass">
          <Name>MPAuthor Registry MonitorTarget</Name>
        </DisplayString>
        <DisplayString ElementID="MPAuthor.RegistryMonitor.View.TargetClass">
          <Name>Registry Monitor Target</Name>
          <Description />
        </DisplayString>
      </DisplayStrings>
    </LanguagePack>
  </LanguagePacks>
</ManagementPack>
