PI Services

Le blog des collaborateurs de PI Services

SCOM – Mise a jour de MP Author en SP3

 

L’outil gratuit de création de management pack de Silect Software a été mis  a jour en SP3

http://www.silect.com/mp-author 

Au menu:

- Amélioration de la visualisation et de l'édition des KB

- Amélioration de l’edition du XML

- Détection des oublis de champs DisplayName

- Possibilité d’utiliser les “Bases classes” a la place de LocalApplication en tant que cible d’une nouvelle classe.

- Affichage d’objets supplémentaires issus des MP

-  Ajout d’une liste dynamique de variable pour la customisation des messages d’alertes.

- Amélioration de la gestion de la mémoire utilisée.

Script Powershell–Scom: Surveillance consommation reguliere de fichiers dans un dossier

 

Le script ci-dessous surveille la consommation (création / suppression) régulière de fichiers dans un dossiers en excluant potentiellement des noms de fichiers et des heures de dernieres modification puis remonte l’état a SCOM.

Lien du script plus bas.

##################################################################################################### #SCRIPT DE SUPERVISION DU CHANGEMENT DE CONTENU DU DOSSIER ARRIVEE POUR L'APPLICATION INVENTAIRE #ETAT KO SI DES FICHIERS SONT PRESENT APRES 15 minutes (CES FICHIERS SONT CENSES ETRE RAPIDEMENT CONSOMMES) ##################################################################################################### #NB: L'INTERVALLE DE TEMPS DE COMPARAISON EST CELLE DE L'INTERVALLE D'EXECUTION DU SCRIPT #SONT EXCLUS DANS LES CRITERES DE RECHERCHE LES FICHIERS CREES ENTRE 22:00 ET 00:59 Param( [string]$computerName, [string]$DirPath, [regex]$excludedfiles="^(FILETOEXCLUDE)|(FILETOEXCLUDE)$", [regex]$filename="^.*(.*)$", [regex]$excludetime="^(22:).*|(23:).*|(00:).*$" ) $scriptname="CheckDirFileConso" #API Scom $api = new-Object -ComObject 'Mom.ScriptAPI' #Verification de l'existence d'une source ayant le nom du script dans l'eventlog operation manager pour loguer certains events Function NewEventSource { if(!(Test-Path "HKLM:\SYSTEM\CurrentControlSet\services\eventlog\Operations Manager\$scriptname")) { New-EventLog -LogName "Operations Manager" -Source $scriptname } } #Verification de l'existence du dossier $DirPath if (!(test-path -Path $DirPath)) { write-host "le dossier $DirPath est introuvable" NewEventSource Write-EventLog -LogName "Operations Manager" -Source $scriptname -EntryType Error -EventId 1004 -Message "le dossier $DirPath est introuvable" Exit } $Files=Get-ChildItem -Path $DirPath | Where-Object {$_.name -match $filename -AND $_.name -notmatch $excludedfiles -AND $_.lastwritetime -lt (get-date).AddMinutes(-15) -AND $_.LastWriteTime.ToLongTimeString() -notmatch $excludetime} | Select-Object -Property Name -ExpandProperty Name If ($Files) { write-host -ForegroundColor yellow -BackgroundColor black "Les fichiers suivants sont présent depuis 15 minutes dans le dossier $DirPath:" foreach ($file in $Files) { write-host $file } NewEventSource Write-EventLog -LogName "Operations Manager" -Source $scriptname -EntryType Warning -EventId 1005 -Message "Les fichiers suivants sont présent depuis 15 minutes dans le dossier $DirPath: $Files" $status="KO" write-host "" write-host -ForegroundColor yellow -BackgroundColor black "ETAT $status" } Else { write-host -ForegroundColor green "Tout les fichiers présents il y a 15 minutes dans le dossier $DirPath ont été consommés" NewEventSource Write-EventLog -LogName "Operations Manager" -Source $scriptname -EntryType Information -EventId 1000 -Message "Tout les fichiers présent il y a 15 minutes dans le dossier $DirPath ont été consommés" $status="OK" write-host "" write-host -ForegroundColor green "ETAT $status" } #Envoi de l'état a SCOM $bag = $API.CreatePropertyBag() If ($status -eq "KO") { $bag.AddValue("Status","Warning") } Else { $bag.AddValue("Status","Success") } $bag

 

 

Rapports SCOM – Ebook gratuit

Un nouvel ebook gratuit est disponible et concerne la création de rapports Reporting Services pour SCOM.

Au menu:

  1. Chapter 1 Operations Manager and the cloud

  2. Chapter 2 Operations Manager reporting basics

  3. Chapter 3 Working with reports

  4. Chapter 4 Overview of report authoring tools

  5. Chapter 5 Authoring reports in Report Builder

  6. Chapter 6 Authoring reports in SQL Server Data Tools

  7. Chapter 7 Building management packs for reporting

  8. Chapter 8 Authoring dashboards in Power View

  9. Chapter 9 Troubleshooting reporting in Operations Manager

 

http://www.microsoftvirtualacademy.com/ebooks#9780735695788

SCOM – VbScript de surveillance de modification régulière d’un dossier

 

Le script suivant surveille qu’un dossier donné en paramètre (chemin au format wmi) est bien modifié régulièrement (Laps de temps en minutes au delà duquel un état KO est généré si le dossier n'a pas été modifié).

Le script est directement utilisable dans un script monitor en passant en paramètre les paramètres strDirName et MinuteOffset.

Lien du script plus bas.

 

Option Explicit '####################################################### 'Script verifiant qu un dossier est bien modifié regulierement 'Le script affiche OK ou KO et repercute l état a SCOM 'ARGUMENTS: 'strDirName(Nom complet du repertoire au format wmi => Ex: D:\\Test\\MyDirectory 'MinuteOffSet(Laps de temps en minutes pendant lequel le dossier n est pas modifié) '####################################################### Dim oArgs Set oArgs = Wscript.Arguments Dim strDirName Dim strComputer Dim objSWbemServices Dim colDirectories Dim objDirectory Dim MinuteOffSet Dim dateNow Dim dateNowMinus Dim oAPI Dim oBag Dim strStatus 'CREATION OBJET SCOM Set oAPI = CreateObject("MOM.ScriptAPI") if oArgs.Count <2 Then 'If the script is called without the required argument, 'create an information event and then quit. wscript.echo "Le script a ete appele sans le nombre minimum d'argument (2)" Call oAPI.LogScriptEvent(WScript.ScriptName,851,0,WScript.ScriptName+" Le script a été appelé sans le nombre minimum d'argument (2)") Wscript.Quit -1 Else 'Log evenement: lancement du script OK Call oAPI.LogScriptEvent(WScript.ScriptName,852,0,WScript.ScriptName+" script was launched successfully") End If '###FONCTION DE FORMATAGE DE DATE########################### function formatDate(format, intTimeStamp) dim unUDate, A ' Test to see if intTimeStamp looks valid. If not, they have passed a normal date if not (isnumeric(intTimeStamp)) then if isdate(intTimeStamp) then intTimeStamp = DateDiff("S", "01/01/1970 00:00:00", intTimeStamp) else response.write "Date Invalid" exit function end if end if if (intTimeStamp=0) then unUDate = now() else unUDate = DateAdd("s", intTimeStamp, "01/01/1970 00:00:00") end if unUDate = trim(unUDate) dim startM : startM = InStr(1, unUDate, "/", vbTextCompare) + 1 dim startY : startY = InStr(startM, unUDate, "/", vbTextCompare) + 1 dim startHour : startHour = InStr(startY, unUDate, " ", vbTextCompare) + 1 dim startMin : startMin = InStr(startHour, unUDate, ":", vbTextCompare) + 1 dim dateDay : dateDay = mid(unUDate, 1, 2) dim dateMonth : dateMonth = mid(unUDate, startM, 2) dim dateYear : dateYear = mid(unUDate, startY, 4) dim dateHour : dateHour = mid(unUDate, startHour, 2) dim dateMinute : dateMinute = mid(unUDate, startMin, 2) dim dateSecond : dateSecond = mid(unUDate, InStr(startMin, unUDate, ":", vbTextCompare) + 1, 2) format = replace(format, "%Y", right(dateYear, 4)) format = replace(format, "%y", right(dateYear, 2)) format = replace(format, "%m", dateMonth) format = replace(format, "%n", cint(dateMonth)) format = replace(format, "%F", monthname(cint(dateMonth))) format = replace(format, "%M", left(monthname(cint(dateMonth)), 3)) format = replace(format, "%d", dateDay) format = replace(format, "%j", cint(dateDay)) format = replace(format, "%h", mid(unUDate, startHour, 2)) format = replace(format, "%g", cint(mid(unUDate, startHour, 2))) if (cint(dateHour) > 12) then A = "PM" else A = "AM" end if format = replace(format, "%A", A) format = replace(format, "%a", lcase(A)) if (A = "PM") then format = replace(format, "%H", left("0" & dateHour - 12, 2)) format = replace(format, "%H", dateHour) if (A = "PM") then format = replace(format, "%G", left("0" & cint(dateHour) - 12, 2)) format = replace(format, "%G", cint(dateHour)) format = replace(format, "%i", dateMinute) format = replace(format, "%I", cint(dateMinute)) format = replace(format, "%s", dateSecond) format = replace(format, "%S", cint(dateSecond)) format = replace(format, "%L", WeekDay(unUDate)) format = replace(format, "%D", left(WeekDayName(WeekDay(unUDate)), 3)) format = replace(format, "%l", WeekDayName(WeekDay(unUDate))) format = replace(format, "%U", intTimeStamp) format = replace(format, "11%O", "11th") format = replace(format, "1%O", "1st") format = replace(format, "12%O", "12th") format = replace(format, "2%O", "2nd") format = replace(format, "13%O", "13th") format = replace(format, "3%O", "3rd") format = replace(format, "%O", "th") formatDate = format end function '##################################################################### '###FONCTION DE CONVERSION DE DATE WMI EN DATE STANDARD (UTC)######### Function WMIDateStringToDate(dtmInstallDate) WMIDateStringToDate = CDate(Mid(dtmInstallDate, 5, 2) & "/" & _ Mid(dtmInstallDate, 7, 2) & "/" & Left(dtmInstallDate, 4) _ & " " & Mid (dtmInstallDate, 9, 2) & ":" & _ Mid(dtmInstallDate, 11, 2) & ":" & Mid(dtmInstallDate, _ 13, 2)) End Function '##################################################################### 'NOM DU DOSSIER AU FORMAT WMI strDirName=oArgs(0) 'NOMBRE DE MINUTES MinuteOffSet=oArgs(1) dateNowMinus=DateAdd("n",-MinuteOffSet,formatDate("%n/%d/%Y %h:%i:%s", Now())) wscript.Echo "FORMAT DE DATE US (MM/dd/YYYY) => SI BESOIN MODIFIER LE FORMATAGE EFFECTUEE PAR LA FONCTION formatDate SUR LA VARIABLE Now" wscript.Echo "" & vbCrLf wscript.Echo "H:" wscript.Echo formatDate("%n/%d/%Y %h:%i:%s", Now()) wscript.Echo "" & vbCrLf wscript.Echo "H-"&MinuteOffSet&"minutes:" wscript.Echo dateNowMinus wscript.Echo "" & vbCrLf strComputer = "." Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") Set colDirectories = objSWbemServices.ExecQuery("select * from win32_directory where name='" & strDirName & "'") For each objDirectory in colDirectories Wscript.Echo objDirectory.Name Wscript.Echo "LastModified: "& WMIDateStringToDate(objDirectory.LastModified) &"" If WMIDateStringToDate(objDirectory.LastModified) > dateNowMinus Then Wscript.Echo "Dossier modifié plus recemment que "& dateNowMinus &" => OK" strStatus="OK" Else Wscript.Echo "Dossier non modifié depuis plus de "& MinuteOffSet &" minutes => KO" strStatus="KO" End If Next Set oBag = oAPI.CreatePropertyBag() If strStatus = "OK" then Call oBag.AddValue("Status","Success") wscript.echo "Healthy" Call oAPI.Return(oBag) Else strStatus = "KO" Call oBag.AddValue("Status","Critical") wscript.echo "Critical" Call oAPI.Return(oBag) End if

 

Orchestrator– Scom: Correlation et “Nettoyage” d’alertes

 

L’interaction Orchestrator-Scom est intéressante sous réserve d’introduire dans les runbooks concernés un peu de corrélation afin de ne pas générer trop d’alerte et de pouvoir les clôturer automatiquement.

L’exemple ci-dessous est un peu limité. En effet:

1/ Le runbook ne détecte pas si une alerte précédente est présente.

2/ Il ne prévoit pas de cas OK associé a une fermeture automatique de l’alerte potentiellement générée avant. (sous réserve que l’on veuille cette clôture automatique) Clignement d'œil

image

 

Ajoutons a ce runbook quelques éléments:

 

image

Si le programme sort OK (Exit = 0) , le nœud “Get Not Closed Alert” cherche les alertes précédemment générées et toujours dans un état autre que Closed, puis si une plusieurs alerte sont trouvées, le nœud Close Alert les clôtures.

Si le programme sort KO (Exit <> 0), le nœud “Get Not Closed Alert” cherche les alertes précédemment générées. Si une alerte est présente, inutile d’en générer une autre pour le même problème, sinon elle est crée par le nœud Create Alerte.

L’idéal, serait dans le second cas d’incrémenter le champ Repeat count de l’alerte existante mais on attends que l’Integration Pack de SCOM intègre cette possibilité dans une prochaine version  Clignement d'œil.

Orchestrator – Script: Ressources utilisées par un runbook

 

Il n’est pas possible directement dans la console Orchestrator de faire le lien entre une instance de runbook et son process policymodule.exe.

Pour cela il faut faire le lien entre le PID du job effectivement en cours d’exécution, dans la base Orchestrator et le PID du process apparent dans le gestionnaire de tache.

Le script suivant prend en paramètre le nom du runbook.

Il est nécessaire de modifier le nom de l’instance SQL ($SQLServer)

Le script renvoi la mémoire (Private Working Set (Ko)) car cette info est particulièrement intéressante mais d’autre compteur peuvent bien sur être récupérés.

 

 

Param( #[parameter(Mandatory=$true)] [string]$Runbook ) $Global:Runbook = $args[0] $Scriptname = "getRunbookJobPid" $SQLServer = "" $SQLDBName = "Orchestrator" $SQLTempDB= "Temp_$Runbook"+"_$Scriptname" #FUNCTIONS function GetProcessInfoById { param ([int]$processId) Get-WmiObject -class Win32_PerfFormattedData_PerfProc_Process | where-object {$_.idprocess -eq $processId} | select ` @{Name="Process Id"; Expression = {$_.idprocess}},` @{Name="Private Working Set (Ko)"; Expression = {$_.workingSetPrivate / 1kb}} } #END_FUNCTIONS $SqlQuery = " SELECT MAX(DATEADD(HOUR,2,TimeStarted)) as TimeStart ,ProcessID as ProcessId ,Name as Name ,j.Status as Jstatus ,RI.status as RIStatus INTO $SQLTempDB FROM [Orchestrator].[dbo].[POLICYINSTANCES] as p WITH (NOLOCK) inner join [Orchestrator].[Microsoft.SystemCenter.Orchestrator.Runtime].[Jobs] as j on j.id=p.JobId inner join [Orchestrator].[Microsoft.SystemCenter.Orchestrator].[Runbooks] as R on R.Id=j.RunbookId inner join [Orchestrator].[Microsoft.SystemCenter.Orchestrator.Runtime].RunbookInstances as RI on RI.RunbookId=R.Id WHERE RI.status = 'InProgress' AND j.Status = 'Running' AND R.Name = '$Runbook' GROUP BY TimeStarted ,ProcessID ,Name ,j.Status ,RI.status DECLARE @MaxDate DateTime SET @MaxDate = (SELECT MAX(TimeStart) FROM $SQLTempDB) SELECT ProcessId from $SQLTempDB WHERE TimeStart = @MaxDate DROP TABLE $SQLTempDB" if (-not($Runbook)) { throw "Nom du runbook requis" } $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() #clear $ProcessId= $DataSet.Tables[0] | Select-Object -Property ProcessId -ExpandProperty ProcessId write-host "RUNBOOK: $Runbook" GetProcessInfoById $ProcessId | fl

Orchestrator – Problème d’affichage de runbook

 

Dans certains cas un runbook nouvellement crée peux ne pas apparaitre dans la console Web ou dans les applications tierces recevant le nom du runbook (SCOM – SCSM).

Pour débuguer ce problème:

- Ouvrez SQL Management Studio et connectez vous a l’instance de la base Orchestrator.

- Exécutez la requête suivante:

Use Orchestrator

TRUNCATE TABLE
[Microsoft.SystemCenter.Orchestrator.Internal].AuthorizationCache

- Rafraichissez l’affichage de la console Web pour faire apparaitre le runbook

 

Pour automatiser la réponse a ce problème, vous pouvez automatiser via un job sql l’exécution de la requête suivante afin de forcer un vidage du cache des autorisations:

Use Orchestrator

EXEC [Microsoft.SystemCenter.Orchestrator.Maintenance].EnqueueRecurrentTask ‘ClearAuthorizationCache’

Windows 2012 Server Manager: Ajout “basique” d’un serveur a gérer.

 

Windows 2012 est clairement orienté Gestion a distance.

Voici comment ajouter rapidement un serveur dans la liste des serveurs gérés

image

Cliquez en haut a droite de la console sur Manage – Add Servers

image

Assurez vous que le nom du serveur a ajouter est bien résolu, ou bien renseignez son IP

image

Une fois découvert, ajoutez le a la sélection de droite, puis OK.

image

Aïe! un message ‘'”Refresh Failed” vous indique que le client WinRm n’a pas pu exécuter la requête.

image

Ouvrez un fenêtre de commande et exécutez la commande:

winrm set winrm/config/client @{TrustedHosts="mcsaw2k12srv1"}

Ceci pour ajouter la machine cible a la liste des serveurs autorisés dans la configuration du client WinRM.

image

Fermez les notification précédentes et réitérer l’ajout du serveur.

Il apparait a présent dans la liste

image

Faites un clic-droit sur le nom et sélectionnez Manage As… si le serveur distant doit être géré avec un compte diffèrent.

image

image

Orchestrator : Requête de l’état des dernières instances de job.

 

Voici une requête a exécuter sur l’instance SQL de votre serveur orchestrator pour récupérer l’état de la dernière exécution d’une liste de runbooks

Vous pouvez de-commenter (—) la clause WHERE pour exclure certain nom de runbook ou encore choisir une des clauses ORDER BY pour choisir un critère de tri.

USE ORCHESTRATOR SELECT RL.Name as RunbookName, MAX(RI.CompletionTime)as dernieredate INTO MyTableau FROM [Orchestrator].[Microsoft.SystemCenter.Orchestrator.Runtime].RunbookInstances as RI INNER JOIN [Orchestrator].[Microsoft.SystemCenter.Orchestrator].Runbooks as RL ON RL.Id=RI.RunbookId --WHERE RL.Name NOT LIKE '%TEST%' GROUP BY RL.Name ORDER BY RL.Name; --ORDER BY MAX(RI.CompletionTime) DESC, RL.Name --ORDER BY LastStatus DESC SELECT RunbookName, dernieredate as Derniere_date_Execution, RI.Status FROM [Orchestrator].[Microsoft.SystemCenter.Orchestrator.Runtime].RunbookInstances as RI INNER JOIN [Orchestrator].[Microsoft.SystemCenter.Orchestrator].Runbooks as RL ON RL.Id=RI.RunbookId INNER JOIN MyTableau ON MyTableau.RunbookName=RL.Name and dernieredate = RI.CompletionTime; GO DROP TABLE MyTableau