PI Services

Le blog des collaborateurs de PI Services

SCOM - Création et peuplement dynamique de groupes à partir d’une clé de registre

 

Note : cet article est inspiré et enrichi de la solution proposée par Jan Van Meirvenne sur son blog.

Une pratique assez courante en entreprise consiste à publier des informations sur les serveurs (rôle, site géographique…) dans des clés de registre « fiches d’identité » créées à cette fin.

Il est alors pertinent de créer des groupes SCOM correspondant à ces clés, afin de pouvoir créer des overrides, de cibler des rôles… en fonction de l’organisation logique déjà en place.

La solution la plus évidente, supportée nativement et réalisable aisément via la console SCOM consiste à étendre la classe Windows Computer à l’aide d’attributs personnalisés, peuplés à partir des clés de registre ; puis à créer des groupes contenant des instances de cette nouvelle classe étendue en filtrant en fonction du contenu de l’attribut étendu.

Cette solution reste cependant fastidieuse : dans le cas d’un grand nombre d’informations différentes (nombreux sites géographiques ou rôles serveur), créer puis maintenir à jour des dizaines de groupes s’avère complexe et peu fiable.

C’est pourquoi il est très intéressant de créer et peupler ces groupes automatiquement.

Commençons par revenir sur ce qu’est un groupe « normal » dans le modèle SCOM : contrairement à la plupart des objets qui sont des instances de classe créées automatiquement par des règles de découverte et hébergées au niveau de l’agent exécuté sur le serveur où se trouve l’objet (par ex une instance de la classe serveur windows, site IIS etc. ), les groupes sont créés de manière unique lorsque vous utilisez l’assistant correspondant et sont hébergés par les Management Servers : ils ne sont pas découverts, ils « commencent à exister » une fois l’assistant terminé.

Ce fonctionnement est propre aux classes qui possèdent l’attribut « singleton », ce qui en fait des classes qui sont également des objets.

Revenons maintenant à notre problème : nous souhaitons créer des groupes basés sur une règle de découverte classique, avec de multiples instances découvertes : il s’agit donc simplement de créer une classe qui dérive de la classe Microsoft.SystemCenter.InstanceGroup (comme tous les groupes), mais qui n’aurait cette fois pas l’attribut singleton.

Il est également nécessaire d’ajouter une propriété clé (key property) à notre classe : cela permet de ne créer qu’une seule instance de la classe même si la propriété est découverte à l’identique sur plusieurs agents ; autrement dit dans notre cas de ne créer qu’un seul groupe correspondant à un attribut géographique même si cet attribut géographique est retrouvé sur de multiples serveurs.

<ClassType ID="TEST.DynamicGroups.Group" Accessibility="Public" Abstract="false" Base="GroupLib!Microsoft.SystemCenter.InstanceGroup" Hosted="false" Singleton="false" Extension="false">

<Property ID="Territory" Type="string" AutoIncrement="false" Key="true" CaseSensitive="false" MaxLength="256" MinLength="0" Required="false" Scale="0" />

</ClassType>

Maintenant que la classe est définie, nous allons pouvoir nous pencher sur la découverte qui découvrira ses instances. Et tant qu’à faire, nous en profiterons pour découvrir également les objets Windows.Computer qui peupleront ces groupes ainsi que la relation qui liera les groupes aux ordinateurs.

La découverte se fera à l’aide d’un script VBS, la seule possibilité pour découvrir à la fois le groupe, l’ordinateur et la relation : évitez donc de définir un intervalle d’exécution trop court pour ne pas surcharger vos agents!

Notez que pour que cette découverte fonctionne, il sera nécessaire d’activer le mode proxy pour tous les serveurs qui seront concernés.

Pensez à modifier la partie en jaune, elle concerne la clé de registre à interroger pour récupérer la valeur qui déterminera le nom du groupe.

<Discovery ID="TEST.DynamicGroups.Group.Discovery" Enabled="true" Target="Windows!Microsoft.Windows.Computer" ConfirmDelivery="false" Remotable="true" Priority="Normal">

<Category>Discovery</Category>

<DiscoveryTypes>

<DiscoveryClass TypeID="TEST.DynamicGroups.Group" />

</DiscoveryTypes>

<DataSource ID="GroupDiscoveryDS" TypeID="Windows!Microsoft.Windows.TimedScript.DiscoveryProvider">

<IntervalSeconds>86400</IntervalSeconds>

<SyncTime />

<ScriptName>discoverdynamicgroups.vbs</ScriptName>

<Arguments>$MPElement$ $Target/Id$ $Target/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Arguments>

<ScriptBody>

SetLocale("en-us")

Dim oAPI
Set oAPI = CreateObject("MOM.ScriptAPI")

Dim oArgs
Set oArgs = WScript.Arguments

if oArgs.Count &lt; 3 Then

Call oAPI.LogScriptEvent("dynamicgroupdiscovery.vbs",101,1,"Script was called with fewer than three arguments and was not executed.")

Wscript.Quit -1

End If

Dim SourceID, ManagedEntityId, TargetComputer

SourceId = oArgs(0)

ManagedEntityId = oArgs(1)

TargetComputer = oArgs(2)

Dim oDiscoveryData, oInstManagedServer,oInstServerGroup,Territory,arrSubKeys

'Lecture de la clef d’identification dans la base de registre

Const HKEY_LOCAL_MACHINE = &amp;H80000002

Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\localhost\root\default:StdRegProv")

oReg.GetStringValue HKEY_LOCAL_MACHINE,"SOFTWARE\TEST\ID_CARD","Territory",Territory

'Construction du nom du groupe et attribution d’une valeur par defaut si clef vide

If IsNull (Territory) Then Territory = "NA"

GroupName = "TEST - TERRITORY - " &amp; Territory

'Ajout de l’instance de l’objet Computer au propertybag

Set oDiscoveryData = oAPI.CreateDiscoveryData(0, SourceID, ManagedEntityID)

set oInstManagedServer = oDiscoveryData.CreateClassInstance("$MPElement[Name='Windows!Microsoft.Windows.Computer']$")

call oInstManagedServer.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", TargetComputer)

call oDiscoveryData.AddInstance(oInstManagedServer)

'Ajout de l’instance de l’objet Group au propertybag

set oInstServerGroup = oDiscoveryData.CreateClassInstance("$MPElement[Name='TEST.DynamicGroups.Group']$")

call oInstServerGroup.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", GroupName)

call oInstServerGroup.AddProperty("$MPElement[Name='TEST.DynamicGroups.Group']/Territory$", Territory)

if Err.Number &lt;&gt; 0 Then

Call oAPI.LogScriptEvent("dynamicgroupdiscovery.vbs",104,1, "Script Error : Can't create ServerGroup (" &amp; Err.Number &amp; ") " &amp; Err.Description)

WScript.Quit -1

End If

call oDiscoveryData.AddInstance(oInstServerGroup)

'Ajout de la relation entre l’objet Computer et l’objet Group

Dim oInstWindowsComputer

set oInstWindowsComputer = oDiscoveryData.CreateClassInstance("$MPElement[Name='Windows!Microsoft.Windows.Computer']$")

call oInstWindowsComputer.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", TargetComputer)

call oDiscoveryData.AddInstance(oInstWindowsComputer)

Set oRelationship = oDiscoveryData.CreateRelationshipInstance("$MPElement[Name='GroupLib!Microsoft.SystemCenter.InstanceGroupContainsEntities']$")

oRelationship.Source = oInstServerGroup

oRelationship.Target = oInstWindowsComputer

Call oDiscoveryData.AddInstance(oRelationship)

if Err.Number &lt;&gt; 0 Then

Call oAPI.LogScriptEvent("dynamicgroupdiscovery.vbs",104,1, "Script Error : Can't create ServerGroup to Computer relationship (" &amp; Err.Number &amp; ") " &amp; Err.Description)

WScript.Quit -1

End If

call oAPI.Return(oDiscoveryData)

</ScriptBody>

<TimeoutSeconds>600</TimeoutSeconds>

</DataSource>

</Discovery>

Le gros de la problématique est maintenant couvert, il ne vous reste plus qu’à intégrer cela à vos propres management packs !

Une dernière note : vu l’utilisation qui sera en général faite de ce MP (overrides, délégations, ciblage pour des vues spécifiques…), il peut s’avérer judicieux de le sceller afin d’être en mesure d’y faire référence depuis d’autres MP.

Ajouter un commentaire

Loading