Jaa


Maintaining State in SCOM Scripts

This post describes a method for maintaining state across script executions in a SCOM Management Pack. This method is appropriate for holding a small amount of numeric or string information (such as timestamps or high water marks). The approach mimics what was used in MOM 2005, so it may also be useful for scripts that are being migrated forward from MOM 2005.

This approach uses the registry to store state information. This isn’t really all that complex to do in a script, but the added value here is a wrapper class that approximates the ease of use that was provided by the state object in MOM 2005.

You’ll have to use your own judgment regarding the applicability of this to your application. Clearly, the registry is not appropriate for storing large amounts of rapidly changing date. It is safe to use this for a few numbers or strings.

See the attachment for a script fragment that contains the VBScript class and associated declarations that provides a convenient registry based State object. Paste this into your script to take advantage of the class.

The state class defines two methods:

· GetState(stateVariableName) – Get the value of a ‘state variable’ from the registry.

· PutState(stateVariableName) – Set the value of a ‘state variable’ in the registry.

The stateVariableName is just a unique name for the item. Pass a string that is descriptive and unique for this value. It is likely that you will need to utilize a naming convention to ensure uniqueness across MPs and scripts.

I couldn’t resist also utilizing the error class that is frequently used scripts found in the Microsoft Management Packs. See the attachment for more details on that class.

Here is an example of using the State object to save information to the registry:

' Put some data in the state object

Dim myDataIn : myDataIn = "save this data"

Call State.PutState("MyVarName", myDataIn)

Here is an example of using the State object to get the data back out of the registry.

' Get the data back out

Dim myDataOut

myDataOut = State.GetState("MyVarName")

 

It couldn’t be simpler. To be absolutely safe, it’s a good idea to embellish this code sample with error checking. Add logic that checks for non-zero value in g_oError.err property after the calls to GetState and PutState.

A few things to note about the State class in the attachment:

1. It uses the RegRead and RegWrite methods of WshShell to the do the actual registry I/O.

2. The secret sauce in this code is in the use of the GetScriptStateKeyPath method provided by the MOM.ScriptAPI script object. This method determines a unique registry path accessible by the current identity. You don’t really need to know the registry path to use the code, but on my machine it is in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\Modules\MyState\S-1-5-21-581608182-3256059318-2886809674-500\Script.

3. Note the argument in the call to GetScriptStateKeyPath("MyState") in the attachment. The “MyState” becomes part of the registry path. Consider using this to uniquely identify your state by management pack or other means.

 

 

StateClass.zip

Comments

  • Anonymous
    May 06, 2009
    OK, several MPS (e.g. AD MPs) use the secret GetScriptStateKeyPath method. However: QUESTION: Is this method of maintaing state really cluster-aware? I wonder why several other MPs use another class instead where SetState ends up writing a file under %windir%temp. (Clearly this is not cluster-aware).