Rapport SCOM sur les espaces disques des serveurs managés

Comment sortir un rapport sur les espaces disques de toutes vos machines supervisées par SCOM. Les rapports standards ne permettent pas de faire cela simplement. Je me suis donc penché sur la question, et voici le résultat que j’expliquerais ensuite. Mon but était de sortir un rapport quotidien, classé par pourcentage d’espace libre afin de faire apparaître les volumes en mal d’espace. J’ai aussi, afin de rendre le rapport visuel, joué sur les couleurs (non visible sur la capture ci-dessous) :

  • Fond Rouge : inférieur à 10%.
  • Fond Orange : entre 10% et 20%.
  • Fond Vert : supérieur à 20%.

Disk report sample

Exemple de rapport espace disque SCOM.

La première chose pour obtenir ce rapport est de collecter l’ensemble des objets nécessaire et de stocker cela dans une table temporaire par exemple. Pour cela, SCOM propose une procédure stockée :

  • Microsoft_SystemCenter_DataWarehouse_Report_Library_ReportObjectListParse.

Cette dernière prend 5 paramètres en entrée (dont 3 obligatoires) :

  • @StartDate : Date de début des objets recherchés.
  • @EndDate : Date de fin des objets recherchés.
  • @ObjectList : XML contenant les paramètres des objets recherchés.

Dans mon exemple, je recherche donc tous les objets supervisés par SCOM sur les 7 derniers jours. Je les trouve donc dans l’objet « Microsoft.SystemCenter.AllComputersGroup »

Pour déterminer le paramètre « @ObjectList », la requête suivante me permets de connaitre l’ID :

select * from vmanagedentity where fullname = 'Microsoft.SystemCenter.AllComputersGroup'

Dans mon cas l’ID est 133. Voici donc ma procédure stockée. Elle demande encore quelques optimisations :

-- ===========================================================
-- Author: Stephan Pfoh
-- Create date: 05/05/2011
-- Description: Extraction pour un rapport de la liste
--  des volumes de tous les serveurs (Taille, FreeSpace, etc.)
-- ===========================================================
CREATE PROCEDURE [dbo].[GetEspaceDisk]
AS
BEGIN
 DECLARE @cmd as varchar(2000)
 DECLARE @ComputerID as int
 DECLARE @ComputerName as varchar(120)
 DECLARE @VolumeName as varchar(120)
 DECLARE @freeAVG as float
 DECLARE @freeMIN as float
 DECLARE @freeMAX as float
 DECLARE @spaceAVG as float
 DECLARE @spaceMIN as float
 DECLARE @spaceMAX as float
 DECLARE @freeDate as datetime
 DECLARE @VolumeSize as float
 -- SET NOCOUNT ON added to prevent extra result sets from
 -- interfering with SELECT statements.
 SET NOCOUNT ON;
 -- Recuperation des instances Windows Computer existant sur la dernière semaine -> table tempo #ManageEntity.
 CREATE TABLE #ManagedEntity (
 ManagedEntityRowId int,
 )
 SET @cmd = 'INSERT INTO #ManagedEntity EXECUTE OperationsManagerDW.[dbo].[Microsoft_SystemCenter_DataWarehouse_Report_Library_ReportObjectListParse] ''' + CAST(convert(date, DateAdd(dd, -7, getdate())) as varchar(10)) + ''', ''' + cast(convert(date, getdate()) as varchar(10)) + ''', '''''
 EXEC(@cmd)
 ALTER TABLE #ManagedEntity ADD
 [Name] [nvarchar](max) NULL,
 [VolumeName] [nvarchar](max) NULL,
 [VolumeSize] [float] NOT NULL DEFAULT 0,
 [FreeAvg] [float] NOT NULL DEFAULT 0,
 [FreeMin] [float] NOT NULL DEFAULT 0,
 [FreeMax] [float] NOT NULL DEFAULT 0,
 [SpaceAVG] [float] NOT NULL DEFAULT 0,
 [SpaceMin] [float] NOT NULL DEFAULT 0,
 [SpaceMax] [float] NOT NULL DEFAULT 0,
 [DateFresh] [smalldatetime] NULL

 -- Cursor sur les LogicalDisk des machines active
 DECLARE WComputer CURSOR FOR
 SELECT RP.ManagedEntityRowId, ME.Name, ME.Path
 FROM OperationsManagerDW.dbo.vManagedEntity ME INNER JOIN #ManagedEntity RP ON ME.ManagedEntityRowId = RP.ManagedEntityRowId
 WHERE ME.FullName like '%LogicalDisk%' AND (Me.Name NOT LIKE '%Volume%' AND Me.Name NOT LIKE '%Mailbox%')
 ORDER BY ME.Path, ME.Name, ME.FullName
 OPEN WComputer FETCH NEXT FROM WComputer INTO @ComputerID, @VolumeName, @ComputerName
 WHILE @@FETCH_STATUS = 0
 BEGIN
 -- Recup % Free Space
 SELECT @freeAVG=ISNULL(p.AverageValue, 0), @freeMIN=ISNULL(p.MinValue, 0), @freeMAX=ISNULL(p.MaxValue, 0), @freeDate=p.DateTime
 FROM OperationsManagerDW.Perf.vPerfDaily p
 INNER JOIN OperationsManagerDW.dbo.vManagedEntity me ON me.ManagedEntityRowID = p.ManagedEntityRowID
 INNER JOIN OperationsManagerDW.dbo.vPerformanceRuleInstance pri ON pri.PerformanceRuleInstanceRowId = p.PerformanceRuleInstanceRowId
 INNER JOIN OperationsManagerDW.dbo.vPerformanceRule pr ON pr.RuleRowId = pri.RuleRowId
 WHERE p.ManagedEntityRowID = @ComputerId AND pr.CounterName = '% Free Space'
 AND p.DateTime = (SELECT MAX(p.DateTime)
 FROM OperationsManagerDW.Perf.vPerfDaily p
 INNER JOIN OperationsManagerDW.dbo.vManagedEntity me ON me.ManagedEntityRowID = p.ManagedEntityRowID
 INNER JOIN OperationsManagerDW.dbo.vPerformanceRuleInstance pri ON pri.PerformanceRuleInstanceRowId = p.PerformanceRuleInstanceRowId
 INNER JOIN OperationsManagerDW.dbo.vPerformanceRule pr ON pr.RuleRowId = pri.RuleRowId
 WHERE p.ManagedEntityRowID = @ComputerId AND pr.CounterName = '% Free Space')
 -- Recup Free Megabytes
 SELECT @spaceAVG=ISNULL(p.AverageValue,0), @spaceMIN=ISNULL(p.MinValue, 0), @spaceMAX=ISNULL(p.MaxValue, 0)
 FROM OperationsManagerDW.Perf.vPerfDaily p
 INNER JOIN OperationsManagerDW.dbo.vManagedEntity me ON me.ManagedEntityRowID = p.ManagedEntityRowID
 INNER JOIN OperationsManagerDW.dbo.vPerformanceRuleInstance pri ON pri.PerformanceRuleInstanceRowId = p.PerformanceRuleInstanceRowId
 INNER JOIN OperationsManagerDW.dbo.vPerformanceRule pr ON pr.RuleRowId = pri.RuleRowId
 WHERE p.ManagedEntityRowID = @ComputerId AND pr.CounterName = 'Free Megabytes'
 AND p.DateTime = (SELECT MAX(p.DateTime)
 FROM OperationsManagerDW.Perf.vPerfDaily p
 INNER JOIN OperationsManagerDW.dbo.vManagedEntity me ON me.ManagedEntityRowID = p.ManagedEntityRowID
 INNER JOIN OperationsManagerDW.dbo.vPerformanceRuleInstance pri ON pri.PerformanceRuleInstanceRowId = p.PerformanceRuleInstanceRowId
 INNER JOIN OperationsManagerDW.dbo.vPerformanceRule pr ON pr.RuleRowId = pri.RuleRowId
 WHERE p.ManagedEntityRowID = @ComputerId AND pr.CounterName = 'Free Megabytes')

 --PRINT CAST(@ComputerID as varchar(10)) + ' - ' + @ComputerName + ' - ' --+ @VolumeName + ' - ' + CAST(@freeDate as varchar(30)) + ' - ' + CAST(@freeAVG as varchar(20)) + ' - ' + CAST(@spaceAVG as varchar(20))
 -- Determine taille du volume
 IF ((@freeAVG IS NULL) OR (@freeAVG = 0)) SET @VolumeSize = 0
 ELSE SET @VolumeSize = ((ISNULL(@spaceAVG, 0)*100)/ISNULL(@freeAVG, 0))/1024

 UPDATE #ManagedEntity SET
 [Name] = @ComputerName,
 [VolumeName] = @VolumeName,
 [VolumeSize] = Round(@VolumeSize,2),
 [FreeAvg] = Round(ISNULL(@freeAVG, 0),2),
 [FreeMin] = Round(ISNULL(@freeMIN, 0),2),
 [FreeMax] = Round(ISNULL(@freeMAX, 0),2),
 [SpaceAvg] = Round(ISNULL(@spaceAVG, 0)/1024,2),
 [SpaceMin] = Round(ISNULL(@spaceMIN, 0)/1024,2),
 [SpaceMax] = Round(ISNULL(@spaceMAX, 0)/1024,2),
 [DateFresh] = DateAdd(d, 1, ISNULL(@freeDate, '01/01/1970'))
 WHERE ManagedEntityRowId = @ComputerID

-- Reinit des variables
 SET @freeAVG = NULL
 SET @freeMIN = NULL
 SET @freeMAX = NULL
 SET @spaceAVG = NULL
 SET @spaceMIN = NULL
 SET @spaceMAX = NULL
 SET @freeDate = NULL

 FETCH NEXT FROM WComputer INTO @ComputerID, @VolumeName, @ComputerName
 END
 CLOSE WComputer;
 DEALLOCATE WComputer;
 SELECT * FROM #ManagedEntity WHERE [Name] IS NOT NULL ORDER BY [Name], [VolumeName]
 DROP TABLE #ManagedEntity
END

(C’est un peu fouillis. Je posterai une version plus lisible ASAP).

Le fonctionnement est assez simple. A partir de la liste des objets actifs sur les 7 derniers jours (choisissez votre période) on crée un « cursor » sur les « LogicalDisk » des machines, et sur chaque objet une requête sur la table « OperationsManagerDW.Perf.vPerfDaily » nous permet de sortir les compteurs nécessaires au rapport. Le tout est stocké dans une table temporaire que je supprime a l’issu de son affichage.

Voici le résultat de son exécution :

Storeproc result

Résultat de la procédure stockée.

On dispose donc de toutes les données nécessaires à la création du rapport :

  • Nom du serveur.
  • Nom du volume.
  • Taille du volume.
  • % Libre moyen (sur les 7 derniers jours).
  • % Libre minimum (sur les 7 derniers jours).
  • % Libre maximum (sur les 7 derniers jours).
  • Espace libre (Mo) moyen (sur les 7 derniers jours).
  • Espace libre minimum (sur les 7 derniers jours).
  • Espace libre maximum (sur les 7 derniers jours).
  • Date de fraicheur. Dernier compteur dans la base. Permets de voir si un agent est HS.

Pour la création du rapport, un prochain article expliquera comment le créer. Dans le cas présent j’ai utilisé Report Builder (téléchargeable ici : http://www.microsoft.com/fr-fr/download/details.aspx?id=6116) qui est très simple d’utilisation.

Cette procédure stockée fonctionne sur SCOM 2007 et 2012.