Imaginons une entreprise qui, pour ses besoins propres d’administration, détermine dans une base de données de référence (CMDB) des ensembles de serveurs sans lien apparent les uns avec les autres, et donc sans possibilité de créer une Discovery basée sur une clé de registre ou une requête WMI.
Le besoin de retrouver cette organisation logique dans SCOM pour positionner des overrides ou cibler des vues peut vite se faire sentir, et il semble alors évident d’intégrer ces serveurs dans un même groupe SCOM.
SCOM ne permet malheureusement pas par défaut d’utiliser une source externe pour peupler un groupe, il faudra donc en passer par la manipulation du code source XML du management pack contenant le groupe afin d’arriver à nos fins. Prêts ? Suivez le guide !
Exportez le management pack contenant le groupe à modifier, et ouvrez le fichier XML dans un éditeur de texte.
Partie 1 : Manifest
Ici, il est nécessaire d’incrémenter la version afin de pouvoir importer le management pack par la suite.
Il faut également s’assurer que les librairies Microsoft.Windows.Library et Microsoft.SystemCenter.InstanceGroup.Library sont référencées :
<ManagementPack ContentReadable="true" SchemaVersion="2.0" OriginalSchemaVersion="1.1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<Manifest>
<Identity>
<ID>TEST</ID>
<Version>1.0.0.1</Version>
</Identity>
<Name>TEST</Name>
<References>
<Reference Alias="MicrosoftWindowsLibrary7585010">
<ID>Microsoft.Windows.Library</ID>
<Version>7.5.8501.0</Version>
<PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
</Reference>
<Reference Alias="MicrosoftSystemCenterInstanceGroupLibrary7585010">
<ID>Microsoft.SystemCenter.InstanceGroup.Library</ID>
<Version>7.5.8501.0</Version>
<PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
</Reference>
</References>
</Manifest>
Partie 2 : TypeDefinitions
Nous allons maintenant définir le groupe qui sera peuplé via la base SQL, ainsi que sa relation.
Pour le groupe, il n’y a rien de très spécial, il y a de fortes chances que votre MP contienne déjà une classe de ce type s’il contient déjà un groupe ; sinon rajoutez la ligne <ClassTypeID …. /> entre les balises <ClassTypes> </ClassTypes> et remplacez Test.Group par un ID correspondant à votre groupe.
Il est, par contre, plus probable qu’il vous faille rajouter la relation. Reprenez le bloc <RelationshipTypes> </RelationshipTypes> et modifiez les parties en rouge pour les adapter à votre contexte.
<TypeDefinitions>
<EntityTypes>
<ClassTypes>
<ClassType ID="Test.Group" Accessibility="Public" Abstract="false" Base="MicrosoftSystemCenterInstanceGroupLibrary7585010!Microsoft.SystemCenter.InstanceGroup" Hosted="false" Singleton="true" Extension="false" />
</ClassTypes>
<RelationshipTypes>
<RelationshipType ID="GroupPopulation.TESTGroupContainsWindowsComputers" Accessibility="Internal" Abstract="false" Base="System!System.Containment">
<Source ID="Source" MinCardinality="0" MaxCardinality="2147483647" Type="Test.Group" />
<Target ID="Target" MinCardinality="0" MaxCardinality="2147483647" Type="MicrosoftWindowsLibrary7585010!Microsoft.Windows.Computer" />
</RelationshipType>
</RelationshipTypes>
</EntityTypes>
</TypeDefinitions>
Section 3: <Monitoring>
Cette section est normalement déjà présente dans votre management pack ; c’est elle qui contient les différents moniteurs et règles, en particulier celle qui nous intéresse ici : la règle de découverte liée à la classe du groupe.
C’est elle qu’il va vous falloir identifier (elle est reconnaissable à sa ligne <Discovery=…. Qui doit contenir la mention Target="TEST.Group"), puis modifier de façon à intégrer un script VBS qui se connectera au serveur SQL et récupérera la liste des serveurs à intégrer au groupe.
Attention : il est nécessaire que le compte SCOM ait accès à la base de données SQL de référence qui contient la liste de vos serveurs !
L’extrait ci-dessous montre l’ensemble de la Discovery que vous devez réutiliser à la place de votre actuelle, en surlignant les parties à adapter à votre contexte :
<Discovery ID="TEST.Group.DiscoveryRule" Enabled="true" Target="TEST.Group" ConfirmDelivery="false" Remotable="true" Priority="Normal">
<Category>Discovery</Category>
<DiscoveryTypes>
<DiscoveryClass TypeID="TEST.Group" />
</DiscoveryTypes>
<DataSource ID="DS" TypeID="MicrosoftWindowsLibrary7585010!Microsoft.Windows.TimedScript.DiscoveryProvider">
<IntervalSeconds>300</IntervalSeconds>
<SyncTime />
<ScriptName>TESTGroupDiscovery.vbs</ScriptName>
<Arguments>$MPElement$ $Target/Id$</Arguments>
<ScriptBody>Dim SourceId
Dim ManagedEntityId
Dim oAPI
Dim oDiscoveryData
Dim objConnection,objConnection2
Dim oRS,oRS2
Dim sConnectString,sConnectStringOPSMGR
SourceId = WScript.Arguments(0)
ManagedEntityId = WScript.Arguments(1)
Set oAPI = CreateObject("MOM.ScriptAPI")
Set oDiscoveryData = oAPI.CreateDiscoveryData(0,SourceId,ManagedEntityId)
sConnectString = "Driver={SQL Server}; Server=REFERENCESQLSERVER\INSTANCE; Database=REFERENCEDATABASE;"
sConnectStringOPSMGR = "Driver={SQL Server}; Server=SCOMSQLSERVER; Database=OperationsManager;"
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Open sConnectString
Set objConnection2 = CreateObject("ADODB.Connection")
objConnection2.Open sConnectStringOPSMGR
Set oRS = CreateObject("ADODB.Recordset")
oRS.Open "SELECT ServerName FROM VServers ", objConnection
Set groupInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='TEST.Group']$")
While Not oRS.EOF
Set oRS2 = CreateObject("ADODB.Recordset")
oRS2.Open "SELECT DISTINCT Id,Path FROM [OperationsManager].[dbo].[ManagedEntityGenericView] WHERE FullName LIKE 'Microsoft.SystemCenter.HealthService:" + LTRIM(RTRIM(oRS.Fields("ServerName"))) + "%'",objConnection2
If Not oRS2.BOF Then
oRS2.MoveFirst
End If
If Not oRS2.EOF Then
Set serverInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='MicrosoftWindowsLibrary7585010!Microsoft.Windows.Computer']$")
serverInstance.AddProperty "$MPElement[Name='MicrosoftWindowsLibrary7585010!Microsoft.Windows.Computer']/PrincipalName$",oRS2.Fields("Path")
Set relationshipInstance = oDiscoveryData.CreateRelationshipInstance("$MPElement[Name='GroupPopulation.TESTGroupContainsWindowsComputers']$")
relationshipInstance.Source = groupInstance
relationshipInstance.Target = serverInstance
oDiscoveryData.AddInstance relationshipInstance
End If
oRS.MoveNext
Wend
objConnection.Close
objConnection2.Close
Call oAPI.Return(oDiscoveryData)
</ScriptBody>
<TimeoutSeconds>120</TimeoutSeconds>
</DataSource>
</Discovery>
Section 4: <LanguagePacks>
Il s’agit simplement ici de rajouter les DisplayString pour les classes nouvellement créées, par exemple :
<DisplayStrings>
<DisplayString ElementID="GroupPopulation.TESTGroupContainsWindowsComputers">
<Name>TEST_from_SQL</Name>
</DisplayString>
</DisplayStrings>
Il ne reste plus ensuite qu’à réimporter ce management pack, et au bout de quelques minutes votre groupe devrait être peuplé par les serveurs contenus dans votre table SQL (à condition bien sûr que ces serveurs soient déjà connus par SCOM, et donc qu’un agent soit déployé dessus !).