PI Services

Le blog des collaborateurs de PI Services

SCOM - Passer la console web en HTTPS

La console SCOM web est très souvent initialement déployée en HTTP simple :  l’utilisation du HTTPS pour les sites web accédés uniquement en local commence tout juste à se démocratiser, le certificat SSL n’a pas forcément été prévu au moment de déployer l’infrastructure SCOM…

Les demandes pour migrer la console en HTTPS commencent cependant à se multiplier, notamment à l’occasion d’un upgrade in-place des infrastructures SCOM 2012 vers 2016 (le cas de SCOM 1801 est un peu différent, la console web ayant totalement été refaite).

On pourrait imaginer qu’il suffit de passer le Default Web Site en HTTPS dans IIS, mais il n’en est rien. Si on se contente de ce paramétrage, la connexion à la console échoue avec le message suivant :

 

System.ServiceModel.CommunicationException: [HttpWebRequest_WebException_RemoteServer]
Arguments: NotFound
Debugging resource strings are unavailable. Often the key and arguments provide sufficient information to diagnose the problem. See http://go.microsoft.com/fwlink/?linkid=106663&Version=5.1.30214.0&File=System.Windows.dll&Key=HttpWebRequest_WebException_RemoteServer ---> System.Net.WebException: [HttpWebRequest_WebException_RemoteServer]
Arguments: NotFound
Debugging resource strings are unavailable. Often the key and arguments provide sufficient information to diagnose the problem. See http://go.microsoft.com/fwlink/?linkid=106663&Version=5.1.30214.0&File=System.Windows.dll&Key=HttpWebRequest_WebException_RemoteServer ---> System.Net.WebException: [HttpWebRequest_WebException_RemoteServer]
Arguments: NotFound

 

Il faut en réalité aussi modifier la configuration de SCOM à deux niveaux :

 

  • Dans le fichier x:\Dossier D’installation\Operations Manager\WebConsole\WebHost\Web.config, dans partie <services>, il faut modifier bindingConfiguration="DefaultHttpBinding" en bindingConfiguration="DefaultHttpsBinding"
  • Dans la clé HKLM\Software\Microsoft\System Center Operations Manager\12\Setup\WebConsole\  de la base de registre, il faut paramétrer :
    • HTTP_GET_ENABLED=false
    • BINDING_CONFIGURATION=DefaultHttpsBinding

 

Ne reste plus qu’à redémarrer iis (iisreset.exe) et le tour est joué!

 

SCOM - Réinitialiser complètement la console

Si vous développez des management packs, il vous est probablement déjà arrivé un bug assez agaçant : les colonnes affichées dans les vues (état, alertes…) ne reflètent pas ce que vous avez défini dans votre code.

L’ordre des colonnes n’est pas respecté, certaines colonnes sont visibles alors qu’elles ne devrait pas l’être et réciproquement…

Et en plus le résultat n’est pas le même d’un utilisateur à l’autre !

Vous connaissez probablement déjà le mode /clearcache de la console, mais cela ne change rien au problème.

Il s’agit en réalité d’une conservation des paramètres de personnalisation des vues dans la base de registre, qui n’est pas affectée par l’utilisation de /clearcache.

Pour réinitialiser complètement la console, une seule solution : fermez la console, lancez regedit et supprimez la clé  HKCU\Software\Microsoft\Microsoft Operations Manager\3.0\Console.

Relancez alors la console (tant qu’à faire en mode /clearcache, pour être sûr) et normalement tout sera rentré dans l’ordre… du moins pour votre profil et sur le poste où vous avez effectué le nettoyage.

Si d’autres utilisateurs/d’autres postes sont impactés, il faudra reproduire la manipulation !

SCOM – SAC ou LTSC ?

Nombre de clients étudient actuellement la migration de leur environnement SCOM 2012 (R2), qui, rappelons-le, a atteint la fin de sa période de support mainstream en juillet 2017.

Il y a actuellement deux possibilités : passer à la version 2016 sortie il y a déjà presque 2 ans ou opter directement pour la version 1801 sortie il y a moins de 2 mois ; sachant qu’il est possible de migrer depuis la version 2012 R2 directement vers ces deux versions, qu’il s’agisse de migration side by side ou in-place.

Commençons par rappeler que ces deux versions ne se distinguent pas par leur architecture ni leur prérequis, ils sont strictement identiques.

La version 1801 étant plus récente, elle contient bien entendu quelques fonctionnalités supplémentaires (et non des moindres, à l’image de la console web enfin 100% html5 et de ses nouveaux dashboards) ; mais ce n’est finalement pas ce qui la différencie fondamentalement de la version 2016. Pour un aperçu détaillé des nouveautés apportées par ces deux versions, technet reste la source la plus appropriée : What’s new in SCOM 2016 et What’s new in SCOM 1801 .

Non, ce qui différencie réellement ces deux versions, c’est plutôt que la sortie de la version 1801 marque la scission en deux branches distinctes de la suite System Center : la Long-Term Service Channel (LTSC) et la Semi-Annual Channel (SAC) ; reprenant ainsi le modèle inauguré avec Windows et SCCM Current Branch.

Ces deux termes désignent le mode de release du produit, autrement dit sa fréquence de parution, sa durée de support et les fonctionnalités qu’il intègre.

Afin de prendre la décision la plus renseignée possible, voici un tour d’horizon de ce que nous savons de ces deux branches… mais aussi (et surtout) de ce que nous ne savons pas encore !

LTSC

Ce mode de release est dans la continuité de ce qui était connu jusqu’ici :

  • Une nouvelle version majeure tous les 3 ans environ, qui devrait suivre les versions LTSC de Windows
  • Une durée de support de 5+5 ans (mainstream+étendu)
  • Des patchs tous les 3-6 mois visant principalement des corrections de bug et de sécurité (Update Rollups)
  • Peu ou pas de nouvelles fonctionnalités pendant la durée de vie du produit

Il n’existe pas encore réellement de release LTSC de System Center (bien qu’on puisse considérer que la version 2016 en est une), mais Microsoft a profité de l’annonce de Windows 2019 pour confirmer la sortie de System Center 2019, qui sera donc la première véritable LTSC (https://cloudblogs.microsoft.com/windowsserver/2018/03/20/introducing-windows-server-2019-now-available-in-preview/).

Il n’est donc pas possible pour le moment d’anticiper avec certitude les choix que Microsoft fera pour cette version, mais certaines suppositions peuvent être faites avec un minimum de fiabilité. Chaque nouvelle version LTSC devrait:

· Intégrer les nouvelles fonctionnalités parues dans les versions SAC précédentes

· Nécessiter d’en passer par une migration pour réaliser le changement de version, qu’elle soit in-place ou side by side, comme pour le passage de SCOM 2012 à 2016 par exemple.

Le mode d’installation des patchs (Update Rollups) devrait rester similaire à ce qui est connu actuellement avec SCOM 2012 et 2016 et devrait donc nécessiter un certain nombre d’étapes manuelles, sans toutefois entrainer d’indisponibilité de la plateforme.

Enfin, s’il semble acquis que la mise à jour vers la future LTSC 2019 sera supportée depuis la version 2016, rien n’indique qu’il sera possible de passer d’une version SAC (1801 et ultérieures) à la version LTSC 2019 ; ni qu’il sera possible de passer de la version LTSC 2019 à une version SAC ultérieure.

Les versions LTSC sont donc à privilégier lorsque la stabilité de l’infrastructure et la durée du support sont les points les plus importants de votre choix.

SAC

Dans ce mode, Microsoft annonce :

  • Une mise à jour tous les 6 mois environ
  • Une durée de support limitée aux 3 dernières versions, donc d’une durée d’environ 18 mois
  • L’ajout régulier de nouvelles fonctionnalités, probablement à chaque mise à jour

Attention : des mises à jour régulières signifient également autant de chances en plus de voir disparaitre des fonctionnalités ou le support de systèmes dépréciés.

La première version SAC est ainsi nommée « SCOM 1801 » en référence à sa date de sortie (Janvier 2018).

On peut donc supposer que la prochaine mise à jour apparaitra en juin-juillet 2018, mais Microsoft n’a pas encore communiqué dessus et n’a donc pas non plus communiqué sur la forme que prendrait cette mise à jour ni sur son mode d’installation.

Il est cependant là aussi possible de faire quelques suppositions à partir des éléments déjà disponibles :

On peut donc s’attendre à ce que le mécanisme de mise à jour vers la prochaine version SAC soit semblable à ce qui existe actuellement pour l’installation des Update Rollups ; autrement dit un processus par définition encore assez manuel mais n’entrainant pas d’indisponibilité de la plateforme.

On peut aussi imaginer qu’un mécanisme « in-console » similaire à celui de SCCM apparaitra à l’avenir, mais il s’agit d’une pure spéculation : Microsoft n’a aucunement communiqué à ce sujet, ni officiellement ni via les demandes de la communauté (https://systemcenterom.uservoice.com/forums/293064-general-operations-manager-feedback/suggestions/33067480-provide-capability-to-apply-update-rollups-from-co )

Par ailleurs, aucune information n’est disponible concernant la possibilité de passer d’une release SAC à une future release LTSC.

Les versions SAC sont donc à privilégier lorsque l’ajout régulier de nouvelles fonctionnalités et le support rapide des nouvelles technologies constituent les points les plus importants, tout en restant vigilant : un cycle de mise à jour rapide peut également entrainer la fin du support de certaines fonctionnalités et technologies à brève échéance (par exemple l’abandon de la supervision d’une ancienne version de Windows, ou l’obligation de mettre à jour la base de données).

Alors, on choisit quoi ?

Comme souvent il n’y a pas de bonne réponse universelle ; d’autant plus ici en raison des nombreuses incertitudes qui entourent encore le futur des 2 branches.

Au final, le choix peut se résumer à cette question : désirez-vous toujours disposer des dernières innovations du produit (ce qui n’est pas un luxe vu le retard qu’il accumule dans certains domaines) au prix d’une potentielle instabilité et au risque de voir disparaitre le support de certaines fonctionnalités ; ou préférez-vous la stabilité et la sécurité apportées par des release plus espacées et plus matures ?

Etant donné la vitesse de l’évolution des technologies (et mon attrait pour les nouvelles fonctionnalités), mon cœur balance évidemment vers la branche SAC. Mais votre point de vue pourrait être tout à fait opposé, et vous pourriez tout aussi bien décider de passer en version 2016 par sécurité, ou d’attendre la sortie en fin d’année de la version LTSC 2019…

SCOM - Les tâches ont disparu de la console

Ces 3 derniers mois, j’ai reçu de plusieurs sources différentes une question concernant la disparition « soudaine » des tâches dans la console lourde SCOM :

image

Autre point commun, ce problème ne concernait à chaque fois que des consoles installées sur des postes utilisateurs, ou publiées sur Citrix. Les tâches étaient par contre bien présentes sur les consoles installées sur les Management Servers, et dans la console Web.

Dans un premier temps, cela me fit penser à une console cliente n’ayant jamais reçu de mise à jour (update rollup) ; c’est un problème que j’avais déjà rencontré il y a quelques années, mais il s’avéra rapidement que cela n’était pas le cas ici.

Une recherche sur le web en me basant sur ces symptômes m’a ensuite orienté vers une quelques articles de blogs assez anciens, indiquant une incompatibilité connue lors de la mise à jour de Savision LiveMaps v1 à v7/8 : https://www.savision.com/knowledge-base/troubleshooting/missing-console-tasks-operations-console-upgrade-live-maps-v78/

Cela semblait cependant assez peu vraisemblable, ces environnements étant beaucoup plus récents. Il me fut d’ailleurs rapidement confirmé qu’ils n’utilisaient de toute facon pas LiveMaps…

Cette piste mis cependant la puce à l’oreille d’un de ces utilisateurs : le problème semblait avoir débuté lors de l’installation de la dernière version (4.0) du management pack HP Oneview, sortie en décembre 2017.

Sa suppression confirma rapidement qu’il était bien le coupable, mais il n’était pas envisageable de se satisfaire de ce contournement, ce management pack étant très utilisé.

Restait donc à trouver où se situait exactement le problème.

Une analyse des journaux d’événements Windows sur les postes concernés par le problème apporta un indice important, puisque l’événement suivant apparaissant dans le journal Application à chaque lancement de la console SCOM:

Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information. : System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
   at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
   at System.Reflection.Assembly.GetTypes()
   at Microsoft.EnterpriseManagement.Presentation.DeclaredAssemblyLoader.LoadModuleCatalogFromAssembly(IModuleCatalog bootstrapperCatalog, ModuleCatalog catalog, Assembly assembly)
   at Microsoft.EnterpriseManagement.Presentation.DeclaredAssemblyLoader.CreateModuleCatalog(IEnumerable`1 assemblies)
   at Microsoft.EnterpriseManagement.Presentation.DeclaredAssemblyLoader.LoadInternal(IEnumerable`1 assemblies)
   at Microsoft.EnterpriseManagement.Presentation.DeclaredAssemblyLoader.Load(DeclaredAssembly assembly)
   at Microsoft.EnterpriseManagement.Monitoring.Components.ComponentRegistry.<>c__DisplayClass3e.<GetAssemblies>b__3c(DeclaredAssembly declaredAssembly)
   at System.Reactive.Linq.Observable.<>c__DisplayClass413`2.<>c__DisplayClass415.<Select>b__412(TSource x)

Cet événement indique que lors de son lancement, la console échoue à charger un ou plusieurs composants dll ; ce qui pourrait facilement laisser à penser que l’installation du MP Oneview ajoute des dépendances à la console SCOM, qui sont absentes des postes clients.

Un incident ouvert auprès du support HP confirma cette dépendance, ainsi que le contournement qui s’imposait : installer la console OneView sur tous les postes disposant de la console SCOM.

Problème réglé !

SCOM – Créer un moniteur d’échantillons consécutifs de performance à 3 états – 2/2

Au cours de l’un ou l’autre des développements de Management Pack que j’ai été amené à réaliser, il est arrivé à plusieurs reprises que l’on me demande de mettre en place un moniteur de performances fonctionnant sur plusieurs mesures consécutives et ayant trois états (healthy/warning/critical), ou autrement dit deux seuils de déclenchement distincts.

Prises séparément, ces deux contraintes ne posent aucune difficulté particulière puisqu’il est possible de créer nativement via la console SCOM des moniteurs de performance de type « consecutive samples » (mesure d’échantillons consécutifs à deux états/un seul seuil) et « double thresholds » (trois états/deux seuils mais déclenchement sur une seule mesure).

Réunir ces deux besoins nécessite par contre d’en passer par un peu d’authoring, ce dont je profiterai pour présenter deux façons de procéder :

- Fusionner deux types de moniteurs natifs

- Utiliser la Suppression, une propriété méconnue de l’expression filter natif (cet article)

Nous avons vu dans la première partie de cet article que nous pouvions utiliser la fusion de deux types de moniteurs natifs pour arriver à nos fins. Cette solution est tout à fait adaptée et peut en plus être réutilisée très largement et s’appliquer à bien d’autres problématiques, mais il existe une autre solution, peut être encore plus élégante à notre problème : le paramètre « Suppression » de l’ExpressionFilter de SCOM.

Dans l’article précédent, j’avais présenté le fonctionnement du type de moniteur Double Threshold et notamment son utilisation de trois Expression Filter successifs.

clip_image002

En allant voir la définition de ce filtre, on constate qu’en plus de travailler sur une Expression, il est capable de travailler sur une Suppression, bien que ce second élément ne soit pas exploité dans la configuration native du type de moniteur Double Threshold :

clip_image004

Ce paramètre de Suppression fonctionne à l’aide de trois paramètres :

- MatchCount : le nombre de fois que l’élément Expression doit matcher avant que le property bag de sortie ne soit effectivement généré

- Sample Count : le nombre de fois que l’Expression Filter doit être évalué avant qu’il soit possible de générer le property bag de sortie.

- Within Seconds : la plage de temps au cours de laquelle l’élément Expression doit matcher avant qu’il soit possible de générer le property bag de sortie.

Il est donc possible d’utiliser Match Count seul ou en combinaison soit avec Sample Count, soit Within Seconds (mais pas les deux) afin d’obtenir une condition de type « l’expression matche 5 fois sur les 10 dernières occurrences » ou « l’expression matche 5 fois sur les 10 dernières minutes ».

Et il est extrêmement simple à utiliser !

Reprenons une fois de plus l’exemple du type de moniteur Double Threshold, et ajoutons une Suppression à la suite de son Expression dans sa condition CDUnderThresold1 :

clip_image005

Voilà, le tour est joué, il ne reste plus qu’à ajouter NumSamples à la configuration de notre type de moniteur personnalisé.

Et comme ici aussi un bon exemple vaut tous les longs discours, voici un fragment complet :

<ManagementPackFragment SchemaVersion="2.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <TypeDefinitions>
    <MonitorTypes>
      <UnitMonitorType ID="Test.ThreeStateConsecutiveThreshold.Suppression.MonitorType" Accessibility="Public">
        <MonitorTypeStates>
          <MonitorTypeState ID="UnderThreshold1"/>
          <MonitorTypeState ID="OverThreshold1UnderThreshold2"/>
          <MonitorTypeState ID="OverThreshold2"/>
        </MonitorTypeStates>
        <Configuration>
          <xsd:element name="ComputerName" type="xsd:string" minOccurs="0" maxOccurs="1"/>
          <xsd:element name="CounterName" type="xsd:string"/>
          <xsd:element name="ObjectName" type="xsd:string"/>
          <xsd:element name="InstanceName" type="xsd:string" minOccurs="0" maxOccurs="1"/>
          <xsd:element name="AllInstances" type="xsd:boolean" minOccurs="0" maxOccurs="1"/>
          <xsd:element name="Frequency" type="xsd:unsignedInt"/>
          <xsd:element name="ScaleBy" type="xsd:double" minOccurs="0" maxOccurs="1"/>
          <xsd:element name="Threshold1" type="xsd:double"/>
          <xsd:element name="Threshold2" type="xsd:double"/>
          <xsd:element name="NumSamples" type="xsd:int"/>
        </Configuration>
        <OverrideableParameters>
          <OverrideableParameter ID="Frequency" ParameterType="int" Selector="$Config/Frequency$"/>
          <OverrideableParameter ID="Threshold1" ParameterType="double" Selector="$Config/Threshold1$"/>
          <OverrideableParameter ID="Threshold2" ParameterType="double" Selector="$Config/Threshold2$"/>
          <OverrideableParameter ID="NumSamples" ParameterType="double" Selector="$Config/NumSamples$"/>
        </OverrideableParameters>
        <MonitorImplementation>
          <MemberModules>
            <DataSource TypeID="Perf!System.Performance.DataProvider" ID="DS1">
              <ComputerName>$Config/ComputerName$</ComputerName>
              <CounterName>$Config/CounterName$</CounterName>
              <ObjectName>$Config/ObjectName$</ObjectName>
              <InstanceName>$Config/InstanceName$</InstanceName>
              <AllInstances>$Config/AllInstances$</AllInstances>
              <Frequency>$Config/Frequency$</Frequency>
              <ScaleBy>$Config/ScaleBy$</ScaleBy>
            </DataSource>
            <ConditionDetection TypeID="System!System.ExpressionFilter" ID="CDUnderThreshold1">
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <XPathQuery Type="Double">Value</XPathQuery>
                  </ValueExpression>
                  <Operator>Less</Operator>
                  <ValueExpression>
                    <Value Type="Double">$Config/Threshold1$</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
              <SuppressionSettings>
                <MatchCount>$Config/NumSamples$</MatchCount>
              </SuppressionSettings>
            </ConditionDetection>
            <ConditionDetection TypeID="System!System.ExpressionFilter" ID="CDOverThreshold1UnderThreshold2">
              <Expression>
                <And>
                  <Expression>
                    <SimpleExpression>
                      <ValueExpression>
                        <XPathQuery Type="Double">Value</XPathQuery>
                      </ValueExpression>
                      <Operator>GreaterEqual</Operator>
                      <ValueExpression>
                        <Value Type="Double">$Config/Threshold1$</Value>
                      </ValueExpression>
                    </SimpleExpression>
                  </Expression>
                  <Expression>
                    <SimpleExpression>
                      <ValueExpression>
                        <XPathQuery Type="Double">Value</XPathQuery>
                      </ValueExpression>
                      <Operator>LessEqual</Operator>
                      <ValueExpression>
                        <Value Type="Double">$Config/Threshold2$</Value>
                      </ValueExpression>
                    </SimpleExpression>
                  </Expression>
                </And>
              </Expression>
              <SuppressionSettings>
                <MatchCount>$Config/NumSamples$</MatchCount>
              </SuppressionSettings>
            </ConditionDetection>
            <ConditionDetection TypeID="System!System.ExpressionFilter" ID="CDOverThreshold2">
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <XPathQuery Type="Double">Value</XPathQuery>
                  </ValueExpression>
                  <Operator>Greater</Operator>
                  <ValueExpression>
                    <Value Type="Double">$Config/Threshold2$</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
              <SuppressionSettings>
                <MatchCount>$Config/NumSamples$</MatchCount>
              </SuppressionSettings>              
            </ConditionDetection>
          </MemberModules>
          <RegularDetections>
            <RegularDetection MonitorTypeStateID="UnderThreshold1">
              <Node ID="CDUnderThreshold1">
                <Node ID="DS1"/>
              </Node>
            </RegularDetection>
            <RegularDetection MonitorTypeStateID="OverThreshold1UnderThreshold2">
              <Node ID="CDOverThreshold1UnderThreshold2">
                <Node ID="DS1"/>
              </Node>
            </RegularDetection>
            <RegularDetection MonitorTypeStateID="OverThreshold2">
              <Node ID="CDOverThreshold2">
                <Node ID="DS1"/>
              </Node>
            </RegularDetection>
          </RegularDetections>
        </MonitorImplementation>
      </UnitMonitorType>
    </MonitorTypes>
  </TypeDefinitions>
  
  
  <Monitoring>
    <Monitors>
      <UnitMonitor ID="Test.ThreeStateConsecutiveThreshold.Suppression.Perf.Monitor" Accessibility="Public" Enabled="true" Target="MWSL!Microsoft.Windows.Server.6.2.LogicalDisk" ParentMonitorID="Health!System.Health.PerformanceState" Remotable="true" Priority="Normal" TypeID="Test.ThreeStateConsecutiveThreshold.Suppression.MonitorType" ConfirmDelivery="false">
        <Category>PerformanceHealth</Category>
        <AlertSettings AlertMessage="Test.ThreeStateConsecutiveThreshold.Suppression.Perf.Monitor.Alert.Message">
          <AlertOnState>Warning</AlertOnState> 
          <AutoResolve>true</AutoResolve>
          <AlertPriority>Normal</AlertPriority>
          <AlertSeverity>MatchMonitorHealth</AlertSeverity>  <!-- Common options for AlertSeverity are MatchMonitorHealth, Information, Warning, Error -->
          <AlertParameters>
            <AlertParameter1>$Data/Context/ObjectName$</AlertParameter1>
            <AlertParameter2>$Data/Context/CounterName$</AlertParameter2>
            <AlertParameter3>$Data/Context/InstanceName$</AlertParameter3>
            <AlertParameter4>$Data/Context/Value$</AlertParameter4>
            <AlertParameter5>$Data/Context/TimeSampled$</AlertParameter5>
          </AlertParameters>
        </AlertSettings>
        <OperationalStates>
          <OperationalState ID="Healthy" MonitorTypeStateID="OverThreshold2" HealthState="Success" />
          <OperationalState ID="Warning" MonitorTypeStateID="OverThreshold1UnderThreshold2" HealthState="Warning" />
          <OperationalState ID="Critical" MonitorTypeStateID="UnderThreshold1" HealthState="Error" />
        </OperationalStates>
        <Configuration>
          <ComputerName>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$</ComputerName>
          <CounterName>% Free Space</CounterName>
          <ObjectName>LogicalDisk</ObjectName>
          <InstanceName>$Target/Property[Type="Windows!Microsoft.Windows.LogicalDevice"]/DeviceID$</InstanceName>
          <AllInstances>false</AllInstances>
          <Frequency>60</Frequency>  <!-- 60 seconds is a good recommended interval for a native module perfmon monitor -->
          <Threshold1>65</Threshold1>
          <Threshold2>80</Threshold2>
          <NumSamples>3</NumSamples>

    
      </Configuration>
      </UnitMonitor>
      
    </Monitors>
  </Monitoring>
  <Presentation>
    <StringResources>
      <StringResource ID="Test.ThreeStateConsecutiveThreshold.Suppression.Perf.Monitor.Alert.Message" />
    </StringResources>
  </Presentation>
  <LanguagePacks>
    <LanguagePack ID="ENU" IsDefault="true">
      <DisplayStrings>
        <DisplayString ElementID="Test.ThreeStateConsecutiveThreshold.Suppression.Perf.Monitor">
          <Name>Test 3State Consecutive Free Disk Space Perf Monitor (Using Suppression)</Name>
          <Description />
        </DisplayString>
        <DisplayString ElementID="Test.ThreeStateConsecutiveThreshold.Suppression.Perf.Monitor" SubElementID="Healthy">
          <Name>Healthy</Name>
        </DisplayString>
        <DisplayString ElementID="Test.ThreeStateConsecutiveThreshold.Suppression.Perf.Monitor" SubElementID="Warning">
          <Name>Warning</Name>
        </DisplayString>
        <DisplayString ElementID="Test.ThreeStateConsecutiveThreshold.Suppression.Perf.Monitor" SubElementID="Critical">
          <Name>Critical</Name>
        </DisplayString>
        <DisplayString ElementID="Test.ThreeStateConsecutiveThreshold.Suppression.Perf.Monitor.Alert.Message">
          <Name>Test 3 state consecutive counter has breached a threshold</Name>
          <Description>The monitor breached a threshold

Object: {0}
Counter {1}
Instance {2}
Has a value {3} 
At time {4}
          </Description>
        </DisplayString>
 
      </DisplayStrings>
    </LanguagePack>
  </LanguagePacks>
</ManagementPackFragment>

 

SCOM – Créer un moniteur d’échantillons consécutifs de performance à 3 états – 1/2

Au cours de l’un ou l’autre des développements de Management Pack que j’ai été amené à réaliser, il est arrivé à plusieurs reprises que l’on me demande de mettre en place un moniteur de performances fonctionnant sur plusieurs mesures consécutives et ayant trois états (healthy/warning/critical), ou autrement dit deux seuils de déclenchement distincts.

Prises séparément, ces deux contraintes ne posent aucune difficulté particulière puisqu’il est possible de créer nativement via la console SCOM des moniteurs de performance de type « consecutive samples » (mesure d’échantillons consécutifs à deux états/un seul seuil) et « double thresholds » (trois états/deux seuils mais déclenchement sur une seule mesure).

Réunir ces deux besoins nécessite par contre d’en passer par un peu d’authoring, ce dont je profiterai pour présenter deux façons de procéder :

- Fusionner deux types de moniteurs natifs (cet article)

- Utiliser la Suppression, une propriété méconnue de l’expression filter natif

Comme vu dans l’introduction, il existe nativement dans SCOM deux types de moniteurs qui, s’ils pouvaient être assemblés, formeraient une solution évidente à notre problème.

Et il se trouve que SCOM permet ce genre de fantaisie assez facilement, bien que cela nécessite de mettre les mains dans le code…

Commençons par aller regarder la « définition » de ces deux types de moniteurs, à l’aide de l’indispensable systemcenter.wiki : ConsecutiveSamplesThreshold et DoubleThreshold

On remarque immédiatement qu’ils sont basés sur une construction très similaire : ils comportent tous les deux en point d’entrée une source de données (Data Source) qui leur permet de récupérer la valeur du compteur de performance qui nous intéressent :
clip_image001

Cette Data Source est suivie par un ensemble de conditions de détection (Condition Detection) qui leur permettent de déterminer quand l’un ou l’autre état du moniteur est atteint.

Pour comprendre leur fonctionnement, il faut imaginer que la valeur relevée par la DataSource passe successivement par chaque Condition Detection, qui, si les conditions qui les définissent sont réunies, vont renvoyer un property bag.

Dans le cas du Consecutive Sample, on trouve trois Condition Detections :

- La première, de type System.Performance.ConsecutiveSamplesCondition, permet de compter le nombre de fois où la valeur du compteur est passée au delà du seuil configuré. Elle n’agit pas directement sur l’état du moniteur.
clip_image002

- La seconde et la troisième, de type ExpressionFilter permettent quant à elles de déterminer deux états pour le moniteur, en fonction de la valeur renvoyée par la première (nombre d’échantillons au-delà du seuil suffisant ou non pour changer l’état).
clip_image004

Dans le cas du Double Threshold, on retrouve également trois Condition Detection, mais ici chacune des trois servent à déterminer l’état du moniteur directement en fonction de la valeur renvoyée par la Data Source (sous le premier seuil, entre les deux seuils ou au-dessus du second):

clip_image006

En se basant sur ces constations, on réalise que rien n’empêche d’écrire nous-même un Monitor Type qui contiendrait à la fois une Condition Detection de type ConsecutiveSamplesCondition pour compter le nombre d’échantillons au-dessus du seuil de détection, suivie de trois ExpressionFilter pour déterminer 3 états différents qui vérifieraient à la fois la valeur du compteur et le nombre de fois qu’il est passé au  delà du seuil!
Le filtre pour l’état « entre deux seuils » ressemblerait donc à cela :

clip_image007

On voit bien que pour que le moniteur prenne l’état « Warning », j’ai simplement créé une expression qui nécessite la réunion de 3 conditions : un nombre de mesures (NumSamples) au-delà du seuil défini et une valeur de ces mesures inférieure à un premier seuil et supérieure à un second.

Et comme un bon exemple complet vaut mieux que tous les longs discours, voici ici le fragment intégral, implémenté pour le compteur « Logical Disk / Free Space % :

<ManagementPackFragment SchemaVersion="2.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <TypeDefinitions>
    <MonitorTypes>
  <UnitMonitorType ID="Test.ThreeStateConsecutiveThreshold.ConditionDetection.MonitorType" Accessibility="Internal">
    <MonitorTypeStates>
      <MonitorTypeState ID="Healthy" NoDetection="false" />
      <MonitorTypeState ID="Warning" NoDetection="false" />
      <MonitorTypeState ID="Critical" NoDetection="false" />
    </MonitorTypeStates>
    <Configuration>
      <xsd:element name="Frequency" type="xsd:integer" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
      <xsd:element name="WarningThreshold" type="xsd:double" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
      <xsd:element name="CriticalThreshold" type="xsd:double" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
      <xsd:element name="NumSamples" type="xsd:integer" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
      <xsd:element name="Direction" type="xsd:string" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
      <xsd:element name="ComputerName" type="xsd:string" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
      <xsd:element name="CounterName" type="xsd:string" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
      <xsd:element name="ObjectName" type="xsd:string" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
      <xsd:element name="InstanceName" type="xsd:string" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
      <xsd:element name="AllInstances" type="xsd:boolean" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
    </Configuration>
    <OverrideableParameters>
      <OverrideableParameter ID="Frequency" Selector="$Config/Frequency$" ParameterType="int" />
      <OverrideableParameter ID="WarningThreshold" Selector="$Config/WarningThreshold$" ParameterType="double" />
      <OverrideableParameter ID="CriticalThreshold" Selector="$Config/CriticalThreshold$" ParameterType="double" />
      <OverrideableParameter ID="NumSamples" Selector="$Config/NumSamples$" ParameterType="int" />

    </OverrideableParameters>
    <MonitorImplementation>
      <MemberModules>
        <DataSource ID="DS" TypeID="Perf!System.Performance.DataProvider">
          <ComputerName>$Config/ComputerName$</ComputerName>
          <CounterName>$Config/CounterName$</CounterName>
          <ObjectName>$Config/ObjectName$</ObjectName>
          <InstanceName>$Config/InstanceName$</InstanceName>
          <AllInstances>$Config/AllInstances$</AllInstances>
          <Frequency>$Config/Frequency$</Frequency>
        </DataSource>
        <ConditionDetection ID="ConsecutiveSamples" TypeID="Perf!System.Performance.ConsecutiveSamplesCondition">
          <Threshold>$Config/WarningThreshold$</Threshold>
          <Direction>$Config/Direction$</Direction>
        </ConditionDetection>
        <ConditionDetection ID="HealthyCondition" TypeID="System!System.ExpressionFilter">
          <Expression>
            <And>
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <XPathQuery Type="Double">SampleValue</XPathQuery>
                  </ValueExpression>
                  <Operator>GreaterEqual</Operator>
                  <ValueExpression>
                    <Value Type="Double">$Config/WarningThreshold$</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <XPathQuery Type="Double">SampleValue</XPathQuery>
                  </ValueExpression>
                  <Operator>GreaterEqual</Operator>
                  <ValueExpression>
                    <Value Type="Double">$Config/CriticalThreshold$</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
            </And>
          </Expression>
        </ConditionDetection>
        <ConditionDetection ID="WarningCondition" TypeID="System!System.ExpressionFilter">
          <Expression>
            <And>
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <XPathQuery Type="Integer">Value</XPathQuery>
                  </ValueExpression>
                  <Operator>GreaterEqual</Operator>
                  <ValueExpression>
                    <Value Type="Integer">$Config/NumSamples$</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <XPathQuery Type="Double">SampleValue</XPathQuery>
                  </ValueExpression>
                  <Operator>LessEqual</Operator>
                  <ValueExpression>
                    <Value Type="Double">$Config/WarningThreshold$</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <XPathQuery Type="Double">SampleValue</XPathQuery>
                  </ValueExpression>
                  <Operator>Greater</Operator>
                  <ValueExpression>
                    <Value Type="Double">$Config/CriticalThreshold$</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
            </And>
          </Expression>
        </ConditionDetection>
        <ConditionDetection ID="CriticalCondition" TypeID="System!System.ExpressionFilter">
          <Expression>
            <And>
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <XPathQuery Type="Integer">Value</XPathQuery>
                  </ValueExpression>
                  <Operator>GreaterEqual</Operator>
                  <ValueExpression>
                    <Value Type="Integer">$Config/NumSamples$</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <XPathQuery Type="Double">SampleValue</XPathQuery>
                  </ValueExpression>
                  <Operator>LessEqual</Operator>
                  <ValueExpression>
                    <Value Type="Double">$Config/CriticalThreshold$</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
            </And>
          </Expression>
        </ConditionDetection>
      </MemberModules>
      <RegularDetections>
        <RegularDetection MonitorTypeStateID="Healthy">
          <Node ID="HealthyCondition">
            <Node ID="ConsecutiveSamples">
              <Node ID="DS" />
            </Node>
          </Node>
        </RegularDetection>
        <RegularDetection MonitorTypeStateID="Warning">
          <Node ID="WarningCondition">
            <Node ID="ConsecutiveSamples">
              <Node ID="DS" />
            </Node>
          </Node>
        </RegularDetection>
        <RegularDetection MonitorTypeStateID="Critical">
          <Node ID="CriticalCondition">
            <Node ID="ConsecutiveSamples">
              <Node ID="DS" />
            </Node>
          </Node>
        </RegularDetection>
      </RegularDetections>
    </MonitorImplementation>
  </UnitMonitorType>
  </MonitorTypes>
  </TypeDefinitions>
  <Monitoring>
    <Monitors>
      <UnitMonitor ID="Test.ThreeStateConsecutiveThreshold.ConditionDetection.Perf.Monitor" Accessibility="Public" Enabled="true" Target="MWSL!Microsoft.Windows.Server.6.2.LogicalDisk" ParentMonitorID="Health!System.Health.PerformanceState" Remotable="true" Priority="Normal" TypeID="Test.ThreeStateConsecutiveThreshold.ConditionDetection.MonitorType" ConfirmDelivery="false">
        <Category>PerformanceHealth</Category>
        <AlertSettings AlertMessage="Test.ThreeStateConsecutiveThreshold.ConditionDetection.Perf.Monitor.Alert.Message">
          <AlertOnState>Warning</AlertOnState>
          <AutoResolve>true</AutoResolve>
          <AlertPriority>Normal</AlertPriority>
          <AlertSeverity>MatchMonitorHealth</AlertSeverity>
          <AlertParameters>
            <AlertParameter1>$Data/Context/ObjectName$</AlertParameter1>
            <AlertParameter2>$Data/Context/CounterName$</AlertParameter2>
            <AlertParameter3>$Data/Context/InstanceName$</AlertParameter3>
            <AlertParameter4>$Data/Context/SampleValue$</AlertParameter4>
            <AlertParameter5>$Data/Context/TimeSampled$</AlertParameter5>
          </AlertParameters>
        </AlertSettings>
        <OperationalStates>
          <OperationalState ID="Healthy" MonitorTypeStateID="Healthy" HealthState="Success" />
          <OperationalState ID="Warning" MonitorTypeStateID="Warning" HealthState="Warning" />
          <OperationalState ID="Critical" MonitorTypeStateID="Critical" HealthState="Error" />
        </OperationalStates>
        <Configuration>
          <Frequency>60</Frequency>
          <WarningThreshold>80</WarningThreshold>
          <CriticalThreshold>65</CriticalThreshold>
          <NumSamples>3</NumSamples>
          <Direction>Less</Direction>
          <ComputerName>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$</ComputerName>
          <CounterName>% Free Space</CounterName>
          <ObjectName>LogicalDisk</ObjectName>
          <InstanceName>$Target/Property[Type="Windows!Microsoft.Windows.LogicalDevice"]/DeviceID$</InstanceName>
          <AllInstances>false</AllInstances>
        </Configuration>
      </UnitMonitor>
    </Monitors>
  </Monitoring>
  <Presentation>
    <StringResources>
      <StringResource ID="Test.ThreeStateConsecutiveThreshold.ConditionDetection.Perf.Monitor.Alert.Message" />
    </StringResources>
  </Presentation>
  <LanguagePacks>
    <LanguagePack ID="ENU" IsDefault="true">
      <DisplayStrings>
        <DisplayString ElementID="Test.ThreeStateConsecutiveThreshold.ConditionDetection.Perf.Monitor">
          <Name>Test 3State Consecutive Free Disk Space Perf Monitor (Condition Detection)</Name>
        </DisplayString>
        <DisplayString ElementID="Test.ThreeStateConsecutiveThreshold.ConditionDetection.Perf.Monitor" SubElementID="Healthy">
          <Name>Healthy</Name>
        </DisplayString>
        <DisplayString ElementID="Test.ThreeStateConsecutiveThreshold.ConditionDetection.Perf.Monitor" SubElementID="Warning">
          <Name>Warning</Name>
        </DisplayString>
        <DisplayString ElementID="Test.ThreeStateConsecutiveThreshold.ConditionDetection.Perf.Monitor" SubElementID="Critical">
          <Name>Critical</Name>
        </DisplayString>
        <DisplayString ElementID="Test.ThreeStateConsecutiveThreshold.ConditionDetection.Perf.Monitor.Alert.Message">
          <Name>Test 3 state consecutive counter has breached a threshold</Name>
          <Description>
            The monitor breached a threshold

            Object: {0}
            Counter {1}
            Instance {2}
            Has a value {3}
            At time {4}
          </Description>
        </DisplayString>
      </DisplayStrings>
    </LanguagePack>
  </LanguagePacks>
</ManagementPackFragment>

 

Direct Access : Mode single-NIC avec deux cartes réseau

Bien qu’il ne s’agisse pas forcément de la configuration la plus fréquente (ni la plus recommandée) dans un environnement de production, il peut arriver qu’il soit nécessaire de réaliser un déploiement de serveurs DirectAccess en mode « single network adapter behind an edge device », autrement dit avec une seule carte réseau connectée dans une DMZ au lieu du fonctionnement plus classique avec une carte réseau sur le LAN et une autre sur Internet :

clip_image002

(image provenant du whitepaper F5 : https://f5.com/resources/white-papers/f5-and-windows-server-2012-directaccessremote-access-services)

Et il peut également arriver que même dans cette configuration, une seconde carte réseau soit présente sur les serveurs DirectAccess, connectée à un réseau totalement différent (par exemple un réseau d’administration isolé, permettant la prise en main à distance des machines de la DMZ).

Dans ce dernier cas, bien que la configuration soit parfaitement correcte (ce qui n’est déjà pas toujours une mince affaire avec DirectAccess…), les clients ne peuvent pas se connecter et on constate des événements IPSec Main Mode « No Policy Configured ».
Par contre, en désactivant la seconde carte réseau puis en redémarrant, le fonctionnement est rétabli ; et a contrario en réactivant la seconde carte le fonctionnement est maintenu tant qu’aucun redémarrage n’a eu lieu.

Ce phénomène se produit lorsqu’au niveau du firewall Windows, la seconde carte réseau est détectée comme ayant un profil « public » et la raison est la suivante : lors du paramétrage de DirectAccess, les règles du firewall permettant de créer le tunnel IPhttps sont créées uniquement pour le profil de firewall « domain », ce qui est souhaité puisque c’est normalement bien le cas de la carte permettant l’accès aux ressources du LAN.

Or l’interface réseau virtuelle IPhttps s’attache de préférence aux cartes réseau dont le profil est « private » ou « public » lorsqu’elles sont présentes : dans ce cas les règles de firewall deviennent donc inopérantes.

Il y a donc deux solutions possibles : faire en sorte que la seconde carte réseau soit également détectée avec un profil « domain » (ce qui n’est pas toujours réalisable), ou modifier la GPO Direct Access afin qu’elle s’applique à tous les profils :

$gposession = Open-NetGPO –PolicyStore <Name of the server GPO>

Set-NetIPsecRule –DisplayName <Name of the IPsec policy> –GPOSession $gposession –Profile Any

Save-NetGPO –GPOSession $gposession

On notera que pour une fois, ce contournement est bien détaillé sur Technet (https://technet.microsoft.com/en-us/library/jj134204.aspx )… mais sur une page où il a bien peu de chances d’être trouvé, puisqu’elle concerne un stade de la configuration de Direct Access ou la GPO n’existe pas et où il n’y a donc aucune raison d’envisager d’y apporter des modifications !

Enfin, attention : il est fort probable qu’il faille réappliquer le contournement à chaque fois que la configuration DirectAccess est modifiée en utilisant l’assistant, puisque ce dernier met à jour la GPO.

PKI : OCSP et bug de certutil

Commençons par quelques rappels : dans le cadre d’un déploiement d’une PKI (public key infrastructure, autrement dit le système permettant l’émission de certificats en entreprise), il est nécessaire d’inclure un ou plusieurs mécanismes de vérification de la révocation des certificats.

Le plus fréquemment utilisé s’appelle la CRL, ou certificate revocation list : il s’agit simplement d’une sorte de fichier texte contenant la liste des certificats révoqués par une autorité donnée, accessible via une classique adresse http. Bien qu’il existe des mécanismes de mise en cache, l’accès à cette liste de révocation peut s’avérer problématique lorsqu’elle commence à devenir volumineuse ou lorsqu’elle est accédée très souvent par de nombreux autres systèmes.

Un autre mécanisme nommé OCSP (online certificate status protocol) permet de pallier à ces limitations : au lieu de télécharger la liste intégrale des certificats révoqués à chaque vérification, il devient possible d’interroger ce service pour lui demander si le certificat n°XXXXX provenant de l’autorité Y est révoqué ou non.

C’est ce second mécanisme qui nous intéresse aujourd’hui, et plus précisément un bug assez surprenant que j’ai rencontré au cours d’un déploiement récent chez un client.

Lors d’un test de la chaine de validation des certificats à l’aide de la commande certutil -urlfetch -verify testcertificat.cer (très utile pour identifier à quel niveau un certificat est refusé, plus d’informations ici par exemple : https://www.sevecek.com/EnglishPages/Lists/Posts/Post.aspx?ID=13 ), je me suis retrouvé avec une exécution incomplète et en boucle des différents tests :

clip_image002

Suivie au bout de quelques secondes par un plantage pur et simple de certutil :

clip_image004

Quelques vérifications rapides me permirent de constater que lorsque le serveur OCSP était rendu indisponible, certutil retrouvait un fonctionnement normal (et indiquait bien sûr l’indisponibilité de l’OCSP) mais impossible d’aller plus loin dans la résolution, et Internet semblait pour une fois muet sur ce souci.

C’est finalement grâce à un collègue qui avait déjà rencontré ce cas que la solution a été trouvée : il s’avère le certificat OCSP Signing doit être émis par l’autorité pour laquelle le serveur OCSP réalise la vérification de révocation, autrement certutil présente ce comportement ; alors que dans ce déploiement c’est l’autorité émettrice qui avait été utilisée pour émettre les certificats OCSP Signing pour la vérification de l’autorité émettrice mais aussi de l’autorité racine (standalone et hors ligne).

La résolution du problème s’impose alors d’elle-même : il faut générer le certificat OCSP Signing sur chacune des autorités dont la vérification sera assurée par le répondeur OCSP, y compris lorsqu’il s’agit d’autorités standalone.

La procédure dans ce cas précis est détaillée sur ce blog : https://blogs.technet.microsoft.com/askds/2009/06/30/implementing-an-ocsp-responder-part-iv-configuring-ocsp-for-use-with-standalone-cas/ .
Notez également qu’il est nécessaire d’ajouter l’extension id-pkix-ocsp-nocheck au préalable (à l’aide de la commande certutil -v -setreg policy\EnableRequestExtensionList +1.3.6.1.5.5.7.48.1.5), car elle n’est par défaut pas disponible sur les autorités standalone.

Enfin, on regrettera que les informations disponibles à ce sujet sur les ressources officielles soient contradictoires, puisqu’on retrouve sur technet les deux passages suivants :

Windows Vista SP1 and Windows Server 2008 enable the OCSP signing certificate implemented by the OCSP responder to use a certificate that terminates in a different root CA than the CA whose revocation information is reported in the OCSP responses. This feature enables an organization with a diverse PKI to limit sources of revocation information and the CAs that can issue OCSP signing certificates.
(https://technet.microsoft.com/en-us/library/ee619736(v=ws.10).aspx au chapitre Independent OCSP signing certificate)

Online Certificate Status Protocol (OCSP) Response Signing certificates need to be signed by the same certification authority (CA) key that was used to sign the end-entity certificates that they provide status for.
( https://technet.microsoft.com/en-us/library/cc754774(v=ws.11).aspx )

SCOM – MP Powershell par SquaredUp

Tous les admins SCOM vous le diront : créer des nouvelles règles dans la console classique peut s’avérer terriblement frustrant, en particulier par son manque de flexibilité et de liberté.

Un exemple particulièrement récurrent est l’impossibilité d’utiliser autre chose que le Visual Basic pour créer des règles ou moniteurs scriptés, alors qu’il est parfaitement possible d’utiliser Powershell en passant par des outils tiers (MP Author de Silect, voire VisualStudio).

Une première tentative de simplifier les choses avait été réalisée par Wei Lim, avec un management pack qui apportait un wizard permettant la création de moniteurs en powershell directement dans la console SCOM : https://blogs.msdn.microsoft.com/wei_out_there_with_system_center/2015/07/09/opsmgr-new-sample-wizard-to-create-powershell-monitors-in-the-ops-console/

Cela restait cependant assez limité, il n’était par exemple pas possible de passer de paramètres aux scripts au début (ce qui fut corrigé dans une release ultérieure) et seule la création de moniteurs à 2 états était possible.

Depuis peu, SquaredUp (société bien connue pour son excellente console web éponyme, nous en reparlerons surement un jour) propose également un management pack gratuit, qui apporte enfin à la console SCOM les fonctionnalités que nous étions en droit d’attendre : création de moniteurs à 2 et 3 états, de tous types de règles, de tâches… en powershell, à l’aide de wizards fort bien concus !

clip_image002

clip_image004

Le Management Pack est disponible ici : https://squaredup.com/free-powershell-management-pack/

Agent SCOM 2012 R2 UR12 (et ultérieur) sur Windows 2003

Lors de la finalisation d’une migration side by side SCOM 2007 vers SCOM 2012 R2, j’ai rencontré un problème assez inattendu : il ne restait alors plus que quelques agents Windows 2003 à déployer et quelques autres à mettre à jour avec le dernier UR, et je n’anticipais pas de problème particulier dans cette phase déjà réalisée à maintes reprises sur d’autres serveurs de cet environnement ainsi que sur d’autres environnements.

J’ai donc eu la mauvaise surprise de constater que ces agents s’arrêtaient dès leur démarrage, parfois sans aucun message d’erreur (arrêt « propre » matérialisé par les événements 103 puis 101), parfois avec un message d’erreur assez peu parlant (événement 1000 après l’événement 103) :

clip_image001

clip_image002

Faulting application healthservice.exe, version 7.1.10292.0, stamp 585161d0, faulting module unknown, version 0.0.0.0, stamp 00000000, debug ? 0, fault address 0x000c9ba0.

J’ai alors décidé de prendre une trace de l’agent, afin d’obtenir un diagnostic plus poussé (cf. https://blog.piservices.fr/post/2017/09/30/SCOM-Prendre-une-trace-de-lagent1).

Fort heureusement le problème était très simple à reproduire (un simple démarrage de l’agent…), et m’a permis d’obtenir l’erreur suivante :

clip_image004

Unable to create self-signed certificate : -2146893816(NTE_BAD_ALGID).

L’agent échoue donc à créer un certificat auto-signé lors de son démarrage, et plante dans la foulée.

Mais pourquoi chercherait-il à générer un certificat ? Comme le précise Stefan Roth dans cet article très détaillé (https://stefanroth.net/2016/03/02/scom-how-data-is-encrypted/), ce certificat est utilisé lorsque le Management Server transmet un RunAs Account à un agent afin d’apporter un niveau de chiffrement supplémentaire.

Ce certificat est donc créé lors du premier démarrage de l’agent, ainsi que lorsqu’il expire (sa durée de vie est d’un an) :

clip_image006

Nous constatons sur la capture ci-dessus que le certificat est bel et bien présent dans le magasin.

Pourquoi l’agent cherche-t-il a le régénérer, et pourquoi échoue-t-il ?

La réponse à la première question se trouve (de façon assez peu claire il est vrai) dans les release notes de l’UR12 de SCOM 2012 R2 :

  • SHA2 support for certificates:  SHA1 is deprecated for the System Center 2012 R2 Operations Manager Agent and SHA2 is now supported.

Autrement dit, le certificat auto-signé de l’agent est maintenant signé avec l’algorithme SHA2 (SHA256RSA) et non plus avec SHA1.

Tant mieux pour la sécurité, SHA1 est aujourd’hui considéré comme déprécié et ne devrait plus être utilisé.

La réponse à la seconde question se trouve encore une fois chez Microsoft : Windows 2003 (et par extension Windows XP) ne supporte pas les algorithmes de la famille SHA2 sans un hotfix qui n’a jamais été intégré aux mises à jour régulières, comme l’indique la KB suivante : http://support.microsoft.com/kb/938397

Une fois le hotfix installé et le serveur redémarré, on constate que l’agent démarre sans encombre et qu’un certificat signé en SHA256 est généré :

clip_image008

Et voilà, problème réglé !