Le blog technique

Toutes les astuces #tech des collaborateurs de PI Services.

#openblogPI

Retrouvez les articles à la une

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 :

<pre class="wp-block-syntaxhighlighter-code"><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>
</pre>

 

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 % :

<pre class="wp-block-syntaxhighlighter-code"><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>
</pre>

 

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.