Le blog technique

Toutes les astuces #tech des collaborateurs de PI Services.

#openblogPI

Retrouvez les articles à la une

SCOM 2012 – Identifier les agents authentifiés par certificat

Dans une infrastructure SCOM, il arrive couramment qu’une petite partie des agents nécessite une authentification par certificat, la plupart du temps lorsqu’ils sont installés sur des serveurs en DMZ, Workgroup ou sur des serveurs membres de domaines ne disposant pas de relation d’approbation.

De ce fait, ils sont la plupart du temps installés manuellement et non pas déployés depuis la console SCOM.

Ces agents nécessitent une attention particulière, car leur gestion diffère des agents déployés plus traditionnellement : ils nécessitent un renouvellement de certificat à échéance régulière, ils ne peuvent pas être mis à jour automatiquement…

Il n’existe pourtant par défaut pas de classe ni de groupe ni de vue dans SCOM qui permette de les identifier rapidement.

J’ai donc développé une classe pour y remédier. Elle se base sur un script VBS qui tourne toutes les 24h et identifie la présence de la chaine ChannelCertificateSerialNumber dans la clé HKLM\SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\Machine Settings et peuple une classe MP_AgentCertificate.Server basée sur Microsoft.Windows.Computer.

Définition de la classe :

<ClassType ID="MP_AgentCertificate.Server" Accessibility="Internal" Abstract="false" Base="Windows!Microsoft.Windows.Computer" Hosted="false" Singleton="false" Extension="false" />

Définition de la découverte :

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

<Category>Discovery</Category>
<DiscoveryTypes>
<DiscoveryClass TypeID="MP_AgentCertificate.Server" />
</DiscoveryTypes>
<DataSource ID="DS" TypeID="Windows!Microsoft.Windows.TimedScript.DiscoveryProvider">
<IntervalSeconds>86400</IntervalSeconds>
<SyncTime />
<ScriptName>regcertdiscovery.vbs</ScriptName>
<Arguments>$MPElement$ $Target/Id$ $Target/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Arguments>

<ScriptBody>
Dim oAPI
Set oAPI = CreateObject("MOM.ScriptAPI")
Dim oArgs
Set oArgs = WScript.Arguments
‘ Check for the required script arguments.
if oArgs.Count &lt; 3 Then
‘ If the script is called without the required arguments,
‘ create an information event and then quit.
Call oAPI.LogScriptEvent("regcertdiscovery.vbs",101,0,"script was called with fewer than three arguments and was not executed.")
Wscript.Quit -1
End If
Dim SourceID, ManagedEntityId, TargetComputer, strComputer

SourceId = oArgs(0) ‘ The GUID of the discovery object that launched the script.
ManagedEntityId = oArgs(1) ‘ The GUID of the computer class targeted by the script.
TargetComputer = oArgs(2) ‘ The FQDN of the computer targeted by the script.
Dim oDiscoveryData, oInst

Set oDiscoveryData = oAPI.CreateDiscoveryData(0, SourceId, ManagedEntityId)
Const HKEY_LOCAL_MACHINE = &amp;H80000002
strComputer = "."
Set StdOut = WScript.StdOut
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &amp; strComputer &amp; "\root\default:StdRegProv")
strKeyPath = "SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\Machine Settings"
strValueName = "ChannelCertificateSerialNumber"

oReg.GetBinaryValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue

if IsNull(strValue) then
StdOut.WriteLine "no cert found"
Call oAPI.LogScriptEvent("regcertdiscovery.vbs",101,0,"no cert found")

else
Call oAPI.LogScriptEvent("regcertdiscovery.vbs",101,0,"cert found")

‘ Discovered the application. Create the application instance.

Set oInst = oDiscoveryData.CreateClassInstance("$MPElement[Name=’MP_AgentCertificate.Server’]$")

‘ Define the property values for this instance. Available

‘ properties are determined by the Management Pack that

‘ defines the class.

Call oInst.AddProperty("$MPElement[Name=’Windows!Microsoft.Windows.Computer’]/PrincipalName$", TargetComputer)
Call oDiscoveryData.AddInstance(oInst)

end if

‘ Submit the discovery data for processing.

Call oAPI.Return(oDiscoveryData) </ScriptBody>

<TimeoutSeconds>600</TimeoutSeconds>
</DataSource>
</Discovery>

Libre à vous ensuite d’intégrer ces éléments à votre propre MP et d’y ajouter des moniteurs ou de créer une vue listant les instances de la classe MP_AgentCertificate.Server etc.

Note : il peut être utile de créer une override qui exécute cette découverte toutes les 10 minutes dans un premier temps, puis de la supprimer lorsque tous les serveurs sont découverts.

Attention si vous utilisez les instances de cette classe pour effectuer des traitements par lot : elle contient tous les agents possédant un certificat, y compris les MS et les Gateways !

Vous trouverez un exemple d’utilisation de cette classe dans l’article Passer des agents en remotely manageable

SCOM 2012 – Impossible de modifier un UserRole

 

Lors de la modification des propriétés d’un User Role (par exemple un changement dans le Scope), le message Parameter UserRoleDisplayName cannot be null apparait au moment de sauvegarder ces changements.

clip_image002

Bien entendu, dans la console SCOM, le champ « user role name » n’est pas vide.

A quoi peut donc être due cette erreur ?

Allons faire un tour dans la base de données, là où sont stockées les localisations :

clip_image004

select LanguageCode,LTValue from LocalizedText

where LTValue like (‘operations manager %operators’)

On remarque immédiatement que le rôle qui nous pose problème (ici Operations Manager Report Operators, mais cela pourrait être n’importe quel role créé après l’installation) comporte un LanguageCode différent, qui correspond normalement à la langue du système depuis lequel a été créé ce role.

On en déduit donc rapidement qu’un rôle créé depuis une console SCOM installée localement sur votre poste personnel (et dont le Windows est en général en francais) prend le LanguageCode correspondant à ce système et devient impossible à modifier depuis une console installée sur un système localisé dans une autre langue, par exemple depuis la console installée sur le serveur SCOM qui est généralement lui en anglais !

En attendant que Microsoft corrige ce problème, les contournements possibles sont assez évidents :

  • Utiliser une console installée sur un Windows localisé dans la même langue que celle qui a servi à créer le rôle
  • Modifier le champ LanguageCode des rôles problématiques afin de les passer en ENU. Notez cependant que Microsoft ne fournit pas de support si vous effectuez des modifications manuelles en base de données en dehors de leurs propres instructions.

Création de tableaux dynamique en Powershell

Nous disposons d’une variable de type tableau avec comme informations des utilisateurs et leurs villes.

Nous allons ici créer dynamiquement une variable pour chaque site présent dans la variable $users et y affecter les utilisateurs.

 

image

Nous allons créer une variable de type tableau dans lesquels nous allons récupérer tous les sites disponibles dans notre variable $users.

$sites=@()

Nous alimentons maintenant la variable $sites.

 

foreach ($user in $users)

{

$sites+=$user.extensionAttribute8

}

$sites=$sites |sort | Get-Unique

 

Résultats :

image

 

Maintenant nous allons créer pour chacun des sites récupérés une variable avec pour nom la valeur récupéré dans la variable $sites

$sites | %{New-Variable -Name $_ -value @() -ErrorAction SilentlyContinue; if ($? -eq $true){write-host "variable créé : $_"}}

Résultats :

image

 

 

Maintenant nous allons alimenter dans les variables créés précédemment dynamiquement les utilisateurs présents dans les sites

foreach ($user in $users)

{

$VariableValue = $Null

$user.extensionAttribute8 |%{$VariableValue = @(((Get-Variable $_).Value)+$user);Set-Variable -name $_ -value $VariableValue}

}

Résultats :

image

image

image

image

image

image

image