How are GUIDs in SCOM and SCSM calculated?

Quite some time ago I discussed with Raphael Burri how GUIDs for SCOM elements are getting calculated. To be honest even with Raphael's great explanation I did not fully understand this topic. Today I read a post from Anton Gritsenko by accident, talking about GUIDs in SCSM and I thought this is the right time to become acquainted with this topic once and for all.

Credits for this post
All credits and knowledge for this post goes completely to Anton Gritsenko for his great post here and to Mihai Sarbulescu for his excellent post here.
I have just summed the topic up in a way that I (and hopefully all other interested people) can understand and hopefully remember this topic.

Why do I need to know this stuff?

Good question. Knowing this stuff answers questions which you might have been asked yourself already:

  • Do you ever wanted to know, why a MP produces different GUIDs in a Lab (where it is unsealed) and a production environment (where it is sealed)?
  • What happens when you use GUIDs for instances or classes in a MP and move the MP between Management Groups (LAB -> Test -> Production)?

Demo XML

For demonstration purposes I created a quick and dirty MP with Silects MP Author (see MP attached). It contains two classes, a discovery and two monitors:

“Static” MP elements vs. “dynamic” instances

When we talk about GUIDs we can roughly distinguish into two main classes of GUIDs:

  • “static” MP Elements
    like the GUID for the MP itself, classes, monitors, rules etc. and
  • “dynamic” (Class) Instances
    like a disk object or a health service object and so on

How are GUIDs for MP elements created?

GUIDs for MP elements are created by using two SQL functions in the OperationsManager db:

  • dbo.fn_MPId for Management Packs
    Example sealed MP: SELECT dbo.fn_MPId('MY.MP.NAME, '%PUBLICKEY%')
    Example unsealed MP: SELECT dbo.fn_MPId('MY.MP.NAME, NULL)
  • dbo.fn_MPObjectId for other Management Pack elements like classes
    Example sealed MP: SELECT dbo.fn_MPObjectId('MY.MP.NAME,'%PUBLICKEY%',‘MY.NEW.CLASS')
    Example unsealed MP: SELECT dbo.fn_MPObjectId('MY.MP.NAME, NULL, 'MY.NEW.CLASS')

When you have a look at the function code you can see, that SCOM combines the function parameter and uses a SHA1 hash function to calculate the GUID:
 

%PUBLICKEY% is the public key (aka KeyToken) of a sealed MP. You can always get this key for any sealed MP by using the get-scommanagementpack Cmdlet.

It is important to note here, that both SQL functions require all uppercase letters, so don’t write e.g. 'My.MP.Name'!

Ok, let’s verify this on an example:
Without importing the MP into a Management Group I check the GUID via PowerShell:

And now let’s verify it with the correct SQL function:

YESS, right GUID.

Now let’s import the MP and verify a class. Again first via PowerShell:

And again with the correct SQL function:

Perfect match!

How are GUIDs for MP instances created?

Ok, what about GUIDs for instances? When we talk about instances we have to deal with two different types of instances:

  • Singleton class instances  (e.g. Groups) and
  • Non-singleton class instances (e.g. Disk objects)

Singleton class instances will be treated like all other classes and will use the function dbo.fn_MPObjectId('MY.MP.NAME, '%PUBLICKEY%', ‘MY.NEW.SINGLETONCLASS ')

Non-singleton class instances will be treated differently and in a much more complex way:

StringToHash = ‘TypeId={<TypeGuid>}[,{<KeyPropertyId>}=<KeyValue>][,{<KeyPropertyId_2>}=<KeyValue_2> ...]’

The string to be hashed will be calculated by combining:

  • the GUID of the target class (TypeID) and
  • all key properties in a way like this:
    {GUID of key property 1}=VALUE_OF_KEY_PROPERTY_IN_UPPERCASE_LETTERS

Sounds complicated? It IS complicated unfortunately. Let’s see an example and start with my demo class which contains only one instance and start again by using PowerShell:

My SCOM.DEMO.GUID.SCOMDEMO.Application class is a child of Microsoft.Windows.LocalApplication. We have to find the key property which can be a bit tricky. In my case, the key property is PrincipalName (5c324096-d928-76db-e9e7-e629dcc261b1) from class Microsoft.Windows.Computer (EA99500D-8D52-FC52-B5A5-10DCD1E9D2BD).

Using Mihai’s SQL function it will look like this:

And again: a perfect match!

Conclusions

Conclusion Nr 1:
MP element GUIDs are calculated based on their Name (MP name, element name) and, if sealed, on the KeyToken of the MP. As long as you do not change one of these properties (e.g. use a new MP seal key), the GUIDs will always be the same, regardless of the Management Group the MP will be imported into.

Conclusion Nr 2:
As soon as you seal (or unseal) a Management Pack and import it into another Management Group, the GUIDs will change, because the KeyToken is one element in the hash function used by the SQL functions.

Conclusion Nr 3:
As long as the key property value won’t change (which his highly unlikely) and we are using sealed MPs the GUID for a class instance is also predictable.

I hope, that this post will shed some light on the creation and calculation of SCOM GUIDs. The same mechanisms are also valid for Service Manager (SCSM).

SCOM.DEMO.GUID.xml