Menu Close

How to create a monitor for existence of a registry key

There are many examples of using a discovery for a new class or extended class, based on a registry key.

What if – you just want to monitor for a specific registry key – and turn your agents to a warning or critical state if it is missing?


Consider the scenario:

CompanyX stamps the registry with Company specific information, like server owner, group, production level, criticality, etc..  They do this by creating a registry key on all systems as part of the build process.  They create this key as HKLM\SOFTWARE\CompanyX, and then have several subkeys and values present.  Perhaps, they use some of this information to populate groups in OpsMgr even.

In the above scenario, the existence of this Registry key becomes critical to monitoring operations.  Therefore – we should ensure that all agents have this key, and alert when a server is introduced without it, or if the key is accidentally deleted.


One common method to do this is to create a simple generic timed script two-state monitor, which will output propertybags indicating the existence of the key or not, and flip monitor state based on the payload in the propertybag.  While this solves the need…. as monitoring workflows like this aggregate – we end up with a LOT of timed scripts, and the total of these script running can have a negative impact on performance.  Also – it requires that you write and debug a VBScript that performs your logic.  This article will describe a method using native OpsMgr modules to accomplish this task without using scripts.


Open the authoring console, and create a new empty management pack.  I called mine ExampleMP.

The idea is to create a monitor for this.  However – every monitor is based on a MonitorType.  There are many MonitorTypes to choose from when creating a monitor that come with the product, like “Basic Service Monitor, Event Timer Reset, Event Manual Reset, etc..”

Since there is no existing MonitorType for “look for the existence of a registry key” we get to create one!

Select “Type Library” and then “Monitor Types”.  Right click > New > Composite Monitor Type.

This will be a composite monitor type because it will contain potentially multiple moduletypes, like datasource, probe, and condition detection.

Give the MonitorType a name (this will be the MonitorType ID).  I chose “ExampleMP.RegExistsMonitorType

On the General tab – give the MonitorType a display name.  I chose “Custom – Check Existence of RegKey Monitor Type

On the States tab – we need to define the state names we want.  This can be anything.  For this example, I will choose “RegKeyExists” and RegKeyMissing”:


On the Member modules tab:  We need to add 3 things for this example.  A datasource to the registry data we need, and two condition detections (one for good (RegKeyExists) and one for bad (RegKeyMissing).

Click Add, and find the “Microsoft.Windows.RegistryProvider” Data Source.  In the ModuleID – this can be anything you want.  Most people just type DS (for DataSource).  I will type in “RegDS” for mine because I like to be different:


We used the Microsoft.Windows.RegistryProvider because this was a good existing Data Source module that has the ability to inspect the registry and has a schedule timer module as well.  To read about all the available modules, check out the TechNet Module Types Reference

On the RegDS Configuration – we have several items we need to input.

For ComputerName – change the default text to:  “$Target/Host/Property[Type=”Windows!Microsoft.Windows.Computer”]/NetworkName$”  (no quotes)  This is a variable which will tell the workflow to connect to the local computer’s registry where it is running.  Described HERE

For AttributeName – this is just a text name to give the attribute of our Reg Key, I will call mine “CompanyXRegExists”.  Described HERE

For Path – this is the path to the custom reg key.  HKLM is assumed – so you will need to add “SOFTWARE\CompanyX”.  Described HERE

For PathType – this is “0” for a key, and “1” for a value.  We are using a key so ours will be “0”.  Described HERE

For Attribute Type – we will use 0 again – for Boolean (true or false).  There options are described HERE

For Frequency – we should input 86400 (this is seconds = 1 day).

For testing in small labs you can set this to be more frequent, just be careful in production with aggressive monitoring on short frequencies.



That completes our datasource!  Next up – add two condition detections.

On the Member Modules tab, click Add, and add the System.ExpressionFilter.  Give our condition detection an ID at the bottom.  I will use “CDExists” for this one.


This condition detection type of System.ExpressionFilter is just a simple filter to be able to add conditional criteria to the output of our monitor type.

For the Expression of this Condition Detection, hit Configure.  Select “Insert”.  For the Parameter name – we need the name of the attribute we used in the data source.  We used “CompanyXRegExists” so type that in here… but it MUST be prefaced with “Values/” so the final line to be added is “Values/CompanyXRegExists”.  Set this to “Equals” and “true”.  Click OK twice to accept our CD.



Now, back on the Member Modules tab, add another Condition Detection of the same type, but call this one “CDMissing”.  We will configure this one identical to the above – but will set the Expression to “Values/CompanyXRegExists” and “Equals” and “false”.



On the Regular tab, we need to define the order or operations for each state.  On the “RegKeyExists” we want the DataSource first, then the Condition Detection for “exists”, then output the module data.



Do the same thing for the RegKeyMissing state, but use the other condition detection for missing:




Click OK, and our MonitorType is done!


Phew!  That is complicated if you haven’t had much experience with the authoring console.  The more you work with it, and the more you get used to typical operations and module types to choose from, the more it will make sense.

So – we have created our MonitorType.  Now we just need to create the monitor that will use this.  That part is a LOT easier.

Select the Health Model pane of the Authoring Console.

Select Monitors.  Right click > New > Custom Unit Monitor.

Give the Monitor an ID.  I chose “ExampleMP.CompanyXRegExistsMonitor

Give the Monitor a good Display Name.  I chose “Custom – Monitor for Existence of Company X Registry

For the Target, I need this to run on all my Windows Servers, so I like to use “Microsoft.Windows.Server.OperatingSystem” (Windows Server Operating System).

For the Parent Monitor  NEVER accept the default.  You always need to choose Availability, Configuration, Performance, or Security.  Since this is really a Configuration issue, I choose System.Health.ConfigurationState:


On the Configuration tab – we need to select a MonitorType for this monitor to use.  Click “Browse for a Type” and select the MonitorType we previously created.

On the Health tab – we need to define each operational state:


On the Alert tab – you can optionally create an alert when this monitor is in a warning Health state, and configure those typical items.

Click OK, and we are done!

You can now import this MP into your test/dev management group, and begin testing.  First – save your MP to a file for backup purposes.  Then, from the authoring console > Tools > Export MP to Management Group > Select your Dev MG, and the auth console with import this directly into it for quick testing.

You should see any Windows Server Operating System object that is missing that registry key, turn to a warning state.  This should be very clear in health explorer:




I have attached my XML for reference


    • Kevin Holman

      Absolutely. You just have to add multiple searches in the datasource, and then multiple expressions in an “and” expression. Or, just create a monitor for each reg key.

  1. Art Dunn

    When trying to follow this in SCOM 2019, I don’t see any way to create a custom monitor type as you’ve explained here. Have things changed in SCOM 2019 that this is no longer possible? I assume my only option is to use a timed script with either VB or PowerShell.

Leave a Reply

Your email address will not be published.