PI Services

Le blog des collaborateurs de PI Services

SCOM 2012 - exploiter le contenu d’évènements stockés dans la base de donnée pour créer une alerte

 

De nombreux Management Pack SCOM créent des évènements dans la base SCOM (visibles dans la console SCOM via les vues Events).

C’est notamment le cas du MP de collecte  et de formatage d’évènements Syslog que je vous ai proposé dans un billet précédent.

Ces évènements n’ont bien sur que peu d’utilité s’ils ne sont pas traités pour obtenir des alertes ou des courbes de performance…

Je vais ici expliquer comment exploiter ces informations à l’aide d’une règle d’alerte qui exécute un script powershell.

Contexte : il a été demandé de générer une alerte lorsqu’un évènement syslog provenant d’un device réseau n’est pas recu un certain nombre de fois dans un laps de temps donné…. J’ai retourné le problème dans tous les sens mais il n’est à ma connaissance pas possible d’y répondre à l’aide d’un workflow utilisant des datasource et des conditions des librairies “standard”.

La solution la plus simple est alors de stocker tous les évènements syslog proprement formatés dans la base SCOM, et de les traiter à l’aide d’un script.

Voyons d’abord comment il est constitué dans son ensemble, je détaillerai chaque partie ensuite :

                <ScriptBody>
param($IPAddress)

$api = new-object -comObject 'MOM.ScriptAPI'
$bag = $api.CreatePropertyBag()


$SQLServer = (Get-ItemProperty -path 'HKLM:\SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\Setup\').databaseservername
$SQLDBName = (Get-ItemProperty -path 'HKLM:\SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\Setup\').databasename
$SqlQuery = "SELECT TOP 2 * FROM [OperationsManager].[dbo].[EventView] where channel like 'syslog' AND LoggingComputer = '" +  $ipaddress + "'  AND EventData like '%Sophos pattern update failed: File transfer failed%' ORDER BY TimeGenerated DESC"
$sqlquery

$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server = $SQLServer; Database = $SQLDBName; Integrated Security = True"

$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = $SqlQuery
$SqlCmd.Connection = $SqlConnection

$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd

$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet)

$SqlConnection.Close()

$referencedate = (get-date).addhours(-4).touniversaltime()

$result = ($DataSet.Tables[0] | where {$_.timegenerated -gt $referencedate} | measure).count

if ($result -ge "2")
{
$status = "KO"
$api.LogScriptEvent('Mirapoint CheckSophosTransferFailed Result : KO ',20,4,$ipaddress)
}

else {$status = "OK"
$api.LogScriptEvent('Mirapoint CheckSophosTransferFailed Result : OK ',20,4,$ipaddress)
}


if ($status -eq "KO") { $bag.AddValue('Status','Bad') }
else { $bag.AddValue('Status','Good') }

$bag

</ScriptBody>

Passons aux explications détaillées :

param($IPAddress) permet juste de récupérer l’adresse IP, passée en paramètre du script. C’est elle qui nous permet d’identifier les évènements correspondant au bon device réseau supervisé.

$SQLServer et $SQLDBName sont des variables qui récupèrent le nom du serveur et de la base SQL de SCOM dans la base de registre du serveur MS sur lequel s’execute le script (comme la règle est ciblée sur des device réseau, le script s’execute sur le MS qui gère le périphérique et non pas sur l’agent)

$SqlQuery est la requête SQL sur laquelle va s’appuyer le traitement du script. La partie “FROM [OperationsManager].[dbo].[EventView]” est obligatoire car il faut requêter la vue EventView pour accéder aux évènements SCOM. Pour le reste, libre à vous d’adapter à votre besoin!

Tout le bloc entre $SqlConnection et $SqlConnection.close() peut être recopiée tel quel, il contient les cmdlet permettant d’effectuer la connexion à la base SQL, d’exécuter la requête et de récupérer son résultat dans la variable $DataSet.Tables[0] .

Le reste du code contient la logique du script et dépend donc de vos besoins, rappelez vous simplement de finir votre script en peuplant puis en retournant le propertybag :

if ($status -eq "KO") { $bag.AddValue('Status','Bad') }
else { $bag.AddValue('Status','Good') }

$bag

Je ne saurais trop vous recommander de tester votre script “en dehors” du management pack avant de l’y intégrer car il peut vite devenir complexe… une fois satisfait, créez votre règle basée sur une probe Microsoft.Windows.PowerShellPropertyBagProbe par exemple comme le décrit Microsoft : https://social.technet.microsoft.com/wiki/contents/articles/16752.management-pack-composition-exercise-2-creating-a-monitor-based-on-a-windows-powershell-script.aspx

Ajouter un commentaire

Loading