PI Services

Le blog des collaborateurs de PI Services

Office 365 - Nettoyer un compte

 

Lorsqu’on se contente de supprimer un compte dans Office365, que ca soit via la console Web ou via powershell, il n’est pas réellement totalement détruit et cela peut occasionner des comportements étranges s’ils sont resynchronisés par la suite.

Afin d’y remédier, il est possible de forcer la suppression totale de ce compte via powershell.

Commencer par supprimer de facon classique le compte :
Remove-MsolUser -UserPrincipalName utilisateur@domaine.com

Puis forcer le nettoyage :
 Get-MsolUser -ReturnDeletedUsers -UserPrincipalName utilisateur@domaine.com | Remove-MsolUser RemoveFromRecycleBin -Force

Il est maintenant possible de relancer un DirSync et l’utilisateur sera intégralement resynchronisé comme s’il n’avait jamais existé.

Office 365 - Synchroniser des utilisateurs en mailuser avec DirSync

 

Si vous utilisez Office 365 dans votre infrastructure, il y a de fortes chances que vous soyez déjà utilisateur de DirSync pour synchroniser votre AD local.

Synchronisation d’utilisateurs locaux en utilisateurs distants ou de Mail Enabled Users locaux en MailUser distants ne vous posent évidemment aucun souci particulier.

Mais comment faire si vous souhaitez sortir des sentiers battus et synchroniser vos utilisateurs en mailuser distants (ce qui constitue un prérequis à l’utilisation de certains outils de migration)?

Commençons par le début : qu’est-ce qui définit un MailUser? Ce blog technet nous apprend qu’il suffit que les attributs mailNickName, DisplayName et TargetAddress soient peuplés.

Seulement voilà : si vos utilisateurs disposent normalement déjà d’un mailnickname et d’un displayname, il en va tout autrement de la targetaddress qui est normalement utilisée afin de rediriger les mails qui leur sont adressés : aucune chance donc que leurs comptes comportent déjà cet attribut, encore moins paramétré vers leur propre adresse, ce qui créerait des boucles de routage.

Il faut donc trouver un moyen de rediriger l’adresse mail de l’utilisateur local vers le champ targetadress de son compte synchronisé dans office 365.

Et cette solution, c’est DirSync : moyennant quelques paramétrages, il va nous permettre ce tour de passe-passe.

Lancez la console MIIS DirSync (elle se trouve par défaut ici : "C:\Program Files\Windows Azure Active Directory Sync\SYNCBUS\Synchronization Service\UIShell\miisclient.exe" ) et ouvrez l’onglet Management Agents

image

Double-cliquez sur Active Directory Connector puis cliquez sur l’onglet Configure Attribute Flow

image

Déplier la catégorie Object Type : user.

Dans le menu déroulant Data source object type, sélectionner user puis dans la liste Data source attribute, sélectionner mail.
Dans mapping type, cocher Direct.
Dans Flow Direction, cocher Import
Dans le menu déroulant Metaverse object type, sélectionner person
Dans la liste Metaverse attribute, sélectionner targetAddress

Cliquer sur New puis sur OK

image

 

Et… c’est tout. Désormais, lorsque les utilisateurs seront synchronisés depuis l’AD vers la metaverse (base de donnée intermediaire de DirSync), l’attribut targetAddress sera peuplé avec leur adresse mail; puis quand DirSync synchronisera la metaverse vers Office365, les utilisateurs seront synchronisés en tant que MailUser.

SCOM 2012 – Faire fonctionner l’enregistrement de session de navigation Web dans Internet Explorer 10 et 11

 

Si l’on s’en fie à Technet, ( http://technet.microsoft.com/en-us/library/hh457546.aspx ), l’utilisation d’IE 10 (et par extension IE 11) n’est pas supportée pour réaliser l’enregistrement d’une session de navigation Web dans SCOM.

Un test rapide le confirme : le plugin Web Recorder ne se charge pas.

On pourrait croire qu’il s’agit du problème bien connu de compatibilité du plugin avec IE x86/x64 (http://social.technet.microsoft.com/wiki/contents/articles/1307.scom-howto-use-the-webrecorder-on-windows-64bit.aspx), mais il n’en est rien…

Fort heureusement, il reste possible de faire fonctionner l’enregistrement dans IE 10 et 11 moyennant quelques ajustements.

Dans Internet Explorer, ouvrir le menu Outils > Options Internet, onglet Avancé.
Vérifier que les cases Activer les extensions tierce partie du navigateur (Enable third party browser extensions) et Activer le mode protégé amélioré (Enable Enhanced Protected Mode) sont cochées et les cocher si elles ne le sont pas.

clip_image002

Quitter IE et ouvrir l’éditeur de registre regedit.

Naviguer jusqu'à la clé de registre suivante : HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main
Ajouter une entrée de type DWORD nommée TabProcGrowth et lui donner la valeur 0

clip_image004

Puis naviguer jusqu’à la clé HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Discardable\PostSetup\Component Categories64\
Supprimer les deux sous-clés {00021493-0000-0000-C000-000000000046} et {00021494-0000-0000-C000-000000000046} . Ces clés correspondent à un cache d’information concernant le plugin WebRecorder, les supprimer force donc IE à remettre en cache ces informations.

Redémarrer l’ordinateur sur lequel est effectuée la capture si des modifications ont été apportées aux paramétrages avancés d’Internet Explorer.

Relancer une capture depuis SCOM. Au lancement d’IE, la barre apparait :

clip_image006

Alternativement, un prompt d’activation du plugin peut apparaitre au lancement d’IE (accepter l’activation) et il peut être nécessaire d’afficher la barre Web Recorder via le menu Affichage > Volets d’Exploration.

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

 

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

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

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

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

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

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

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

                <ScriptBody>
param($IPAddress)

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


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

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

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

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

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

$SqlConnection.Close()

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

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

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

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


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

$bag

</ScriptBody>

Passons aux explications détaillées :

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

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

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

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

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

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

$bag

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

SCOM 2012 – collecter et formater des évenements syslog

 

Comme vous le savez probablement déjà, SCOM permet de créer des règles d’alerte basées sur la collecte d’événements syslog.

Ces événements collectés ont malheureusement le gros défaut d’être « bruts », sans aucun formatage ni filtrage des champs : ils sont stockés comme un gros bloc de texte dans la base de donnée.

Ce n’est pas idéal si votre objectif est de leur appliquer un traitement complexe, par exemple à l’aide d’un script (plus de détails à ce sujet dans un prochain billet).

Il est cependant simple d’y remédier, à condition d’accepter de mettre la main à la pâte, car la DataSource utilisée n’est disponible dans aucune template prédéfini… on n’a rien sans rien.

Avant de débuter, un petit rappel : une règle utilisant une datasource Syslog doit être ciblée sur la classe « Agent » et elle va activer l’écoute de l’agent SCOM sur le port syslog pour tous les serveurs ciblés : il est donc fortement recommandé de la désactiver par défaut, et de créer un override d’activation ciblé sur un groupe contenant le ou les agents responsables de la collecte d’évènements syslog.

Voyons maintenant la structure logique de notre Management Pack :

- Classe pour le groupe qui contient les agents responsables de la collecte
- Découverte qui peuple le groupe
- Règle de collecte
- DisplayStrings

C’est bien évidement la règle de collecte qui nous intéresse le plus. Détaillons son contenu :

<Rules>
      <Rule ID="Test.Syslog.CollectionRule" Enabled="false" Target="SC!Microsoft.SystemCenter.Agent" ConfirmDelivery="true" Remotable="true" Priority="Normal" DiscardLevel="100">
        <Category>Custom</Category>
        <DataSources>
          <DataSource ID="SyslogDS" TypeID="ApplicationLog!System.ApplicationLog.SysLog.EventProvider">
            <Port>514</Port>
          </DataSource>
        </DataSources>
        <ConditionDetection ID="GenericDataMapperCD" TypeID="System!System.Event.GenericDataMapper">
          <EventOriginId>$Target/Id$</EventOriginId>
          <PublisherId>$MPElement$</PublisherId>
          <PublisherName>$Data/EventData/DataItem/PriorityName$</PublisherName>
          <Channel>Syslog</Channel>
          <LoggingComputer>$Data/EventData/DataItem/HostName$</LoggingComputer>
          <EventNumber>54321</EventNumber>
          <EventCategory>0</EventCategory>
          <EventLevel>0</EventLevel>
          <UserName />
          <Description>$Data/EventData/DataItem/Message$</Description>
          <Params />
        </ConditionDetection>
        <WriteActions>
          <WriteAction ID="WriteToDB" TypeID="SC!Microsoft.SystemCenter.CollectEvent" />
         
        </WriteActions>
      </Rule>
    </Rules>

Cette règle est, comme vu plus haut, ciblée sur la classe Microsoft.SystemCenter.Agent et désactivée par défaut (enabled=false).

Son workflow est constitué de trois éléments principaux :

- une DataSource de type System.ApplicationLog.SysLog.EventProvider, qui permet d’activer l’écoute de message syslog sur le port spécifié (attention, on ne peut pas avoir deux règles syslog qui s’exécutent sur le même serveur avec le même port!)
- un GenericDataMapper : c’est lui qui va faire la correspondance entre les champs d’un évènement SCOM (EventOrigin, PublisherId, PublisherName, Logging Computer, Description…) et les champs issus du message Syslog. J’utilise aussi des champs aux valeurs hardcodées dans cet exemple (EventNumber, EventLevel…)
- Une WriteAction, qui écrit l’évènements formaté dans la base de donnée.

Simple, non?

Une fois le MP importé et l’override d’activation défini, les évènements devraient apparaitre dans la base de donnée. Attention, la DB de SCOM contient 20 tables pour les évènements, utilisés en roulement. Il est donc bien plus pratique et efficace de passer par la vue EventView qui les regroupe!

 

Pour une vue plus globale, voici un exemple de MP de collecte Syslog complet (il ne reste plus qu’à peupler le groupe et à créer l’override d’activation sur la règle de collecte) :

<?xml version="1.0" encoding="utf-8"?><ManagementPack ContentReadable="true" SchemaVersion="2.0" OriginalSchemaVersion="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <Manifest>
    <Identity>
      <ID>Test.Syslog</ID>
      <Version>1.0.0.0</Version>
    </Identity>
    <Name>Test.Syslog</Name>
    <References>
      <Reference Alias="ApplicationLog">
        <ID>System.ApplicationLog.Library</ID>
        <Version>7.0.8432.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="SCDW">
        <ID>Microsoft.SystemCenter.DataWarehouse.Library</ID>
        <Version>7.0.8432.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="Windows">
        <ID>Microsoft.Windows.Library</ID>
        <Version>7.5.8501.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="MicrosoftSystemCenterInstanceGroupLibrary7585010">
        <ID>Microsoft.SystemCenter.InstanceGroup.Library</ID>
        <Version>7.5.8501.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="System">
        <ID>System.Library</ID>
        <Version>7.5.8501.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="SC">
        <ID>Microsoft.SystemCenter.Library</ID>
        <Version>7.0.8432.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="Health">
        <ID>System.Health.Library</ID>
        <Version>7.0.8432.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
    </References>
  </Manifest>
  <TypeDefinitions>
    <EntityTypes>
      <ClassTypes>
        <ClassType ID="Test.Syslog.Collector.Group" Accessibility="Public" Abstract="false" Base="MicrosoftSystemCenterInstanceGroupLibrary7585010!Microsoft.SystemCenter.InstanceGroup" Hosted="false" Singleton="true" Extension="false" />
      </ClassTypes>
    </EntityTypes>
  </TypeDefinitions>
  <Monitoring>
    <Discoveries>
      <Discovery ID="Test.Syslog.Collector.Group.DiscoveryRule" Enabled="true" Target="Test.Syslog.Collector.Group" ConfirmDelivery="false" Remotable="true" Priority="Normal">
        <Category>Discovery</Category>
        <DiscoveryTypes>
          <DiscoveryRelationship TypeID="MicrosoftSystemCenterInstanceGroupLibrary7585010!Microsoft.SystemCenter.InstanceGroupContainsEntities" />
        </DiscoveryTypes>
        <DataSource ID="GroupPopulationDataSource" TypeID="SC!Microsoft.SystemCenter.GroupPopulator">
          <RuleId>$MPElement$</RuleId>
          <GroupInstanceId>$MPElement[Name="Test.Syslog.Collector.Group"]$</GroupInstanceId>
          <MembershipRules>
            <MembershipRule Comment="EMPTY_RULE_8eadaced-59c8-4ebc-a4e4-b8428a374442">
              <MonitoringClass>$MPElement[Name="System!System.Entity"]$</MonitoringClass>
              <RelationshipClass>$MPElement[Name="MicrosoftSystemCenterInstanceGroupLibrary7585010!Microsoft.SystemCenter.InstanceGroupContainsEntities"]$</RelationshipClass>
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <Value>True</Value>
                  </ValueExpression>
                  <Operator>Equal</Operator>
                  <ValueExpression>
                    <Value>False</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
            </MembershipRule>
          </MembershipRules>
        </DataSource>
      </Discovery>
    </Discoveries>
    <Rules>
      <Rule ID="Test.Syslog.CollectionRule" Enabled="false" Target="SC!Microsoft.SystemCenter.Agent" ConfirmDelivery="true" Remotable="true" Priority="Normal" DiscardLevel="100">
        <Category>Custom</Category>
        <DataSources>
          <DataSource ID="SyslogDS" TypeID="ApplicationLog!System.ApplicationLog.SysLog.EventProvider">
            <Port>514</Port>
          </DataSource>
        </DataSources>
        <ConditionDetection ID="GenericDataMapperCD" TypeID="System!System.Event.GenericDataMapper">
          <EventOriginId>$Target/Id$</EventOriginId>
          <PublisherId>$MPElement$</PublisherId>
          <PublisherName>$Data/EventData/DataItem/PriorityName$</PublisherName>
          <Channel>Syslog</Channel>
          <LoggingComputer>$Data/EventData/DataItem/HostName$</LoggingComputer>
          <EventNumber>54321</EventNumber>
          <EventCategory>0</EventCategory>
          <EventLevel>0</EventLevel>
          <UserName />
          <Description>$Data/EventData/DataItem/Message$</Description>
          <Params />
        </ConditionDetection>
        <WriteActions>
          <WriteAction ID="WriteToDB" TypeID="SC!Microsoft.SystemCenter.CollectEvent" />
          <WriteAction ID="WriteToDW" TypeID="SCDW!Microsoft.SystemCenter.DataWarehouse.PublishEventData" />
        </WriteActions>
      </Rule>
    </Rules>

  </Monitoring>
  <LanguagePacks>

    <LanguagePack ID="ENU" IsDefault="true">
      <DisplayStrings>
        <DisplayString ElementID="Test.Syslog">
          <Name>Test.Syslog</Name>
        </DisplayString>
        <DisplayString ElementID="Test.Syslog.CollectionRule">
          <Name>Syslog - Collection Rule</Name>
          <Description>Cette regle est en charge de la collecte de tous les evenements syslog, quel que soit l'emmeteur.
Chaque agent en charge de la reception des messages syslog doit etre ajoute au groupe Test.Syslog.Collector</Description>
        </DisplayString>
        <DisplayString ElementID="Test.Syslog.Collector.Group">
          <Name>Test.Syslog.Collector</Name>
        </DisplayString>
        <DisplayString ElementID="Test.Syslog.Collector.Group.DiscoveryRule">
          <Name>Populate Test.Syslog.Collector</Name>
          <Description>This discovery rule populates the group 'Test.Syslog.Collector'</Description>
        </DisplayString>
      </DisplayStrings>
    </LanguagePack>
  </LanguagePacks>
</ManagementPack>

 

SCOM 2012 : Deux outils de développement gratuits

 

Si vous êtes administrateur de longue date d’une supervision SCOM, vous regrettez très probablement la disparition de la console Authoring présente dans SCOM 2007.

Elle permettait le développement rapide et (en partie) graphique de Management Packs relativement complexes avec une création assez visuelle des workflow de supervision.

L’arrivée de SCOM 2012 a malheureusement signé l’arrêt de son support : il est toujours possible de créer un MP avec la console Authoring et de l’importer sur une plateforme SCOM 2012, mais il n’est par la suite plus possible de le rouvrir pour le modifier. Il n’est évidemment pas possible non plus de tirer profit des nouvelles fonctionnalités propres à SCOM 2012 (nouveaux Dashboard, nouvelles fonctionnalités de supervision réseau…).

La préconisation de Microsoft était alors de se rabattre sur Visual Studio avec les extensions VSAE (Visual Studio Authoring Extensions), ou sur Visio à l’aide de VMPD (Visio Management Pack Designer) pour les management pack les plus simples.
Nous avions donc le choix entre une solution peu pertinente et très limitée (Visio) et la solution la plus complète qui soit, mais également la moins accessible aussi bien en terme de complexité de mise en œuvre que de coût.

MP Author

Heureusement, après presque 2 ans de disette, les développeurs de Silect (une filiale de Bridgeways, un éditeur de Management Pack) ont entendu notre appel et ont publié l’outil gratuit MP Author (http://www.silect.com/mp-author ), qui rappelle la console Authoring par bien des aspects.

Reprenons par exemple l’exemple classique de la création d’un MP contenant une classe et une découverte à l’aide d’une clé de registre :

L’installation est assez directe (suivant -> suivant -> ok), notez cependant qu’il est nécessaire que la console SCOM 2012 (R2) soit présente.

On crée ensuite un nouveau MP :

clip_image002

On indique un ID, un nom et une description

clip_image004

Dossier d’export

clip_image006

MPs à référencer

clip_image008

Il est préférable de sélectionner Empty Management Pack car le template Single Server Application crée des objets inutiles à une supervision basique

Nous arrivons maintenant à l’écran principal de l’outil, d’une apparence plutôt familière si on a l’habitude de la console Authoring.

Cliquer sur Target > New > Create New Registry Target :

clip_image010

Il est possible de se connecter à un serveur distant pour parcourir sa base de registre à la recherche de la clé appropriée, ou bien d’entrer à la main les informations :

clip_image012

Sélectionner la clé de registre sur laquelle se basera la découverte :

clip_image014

Donner un ID et un nom à la classe :

clip_image016

De même pour la découverte :

clip_image018

Définir une expression pour la découverte :

clip_image020

Définir un intervalle de découverte :

clip_image022

A l’aide d’un assistant très similaire, on ajoute un moniteur qui supervisera le service DHCP :

clip_image024

clip_image026

clip_image028

clip_image030

Il ne reste plus qu’à exporter votre management pack, soit directement vers SCOM à l’aide d’un clic droit sur la racine de l’arborescence à gauche > Import Management Pack :

clip_image032

Soit en sauvegardant le MP sous forme de fichier XML et en l’important via la console SCOM.

Certes, cet outil est moins complet que l’ancienne console Authoring et perfectible sur bien des points, mais il devrait permettre de gagner un temps précieux et remplace avantageusement la solution Visio proposée par Microsoft!

Visual Studio

Le but ici n’est pas de vous proposer une introduction complète à l’utilisation de Visual Studio pour le développement de Management Pack, mais plutôt de vous révéler une astuce : en effet, le titre de ce billet est « deux outils de développement gratuits »…

Et il n’est effectivement pas nécessaire de débourser le moindre centime, ni même de se lancer dans le téléchargement fastidieux d’un iso de plusieurs Go pour obtenir un Visual Studio exécutant les Authoring Extensions de manière parfaitement fonctionnelle !

Voici ce dont vous aurez besoin :

Microsoft Visual Studio 2012 Shell (Isolated) Redistributable Package (220 mo) : www.microsoft.com/en-us/download/details.aspx?id=30670

Microsoft Visual Studio 2012 Shell (Integrated) Redistributable Package (1,5 mo) : http://www.microsoft.com/en-us/download/details.aspx?id=30663

System Center 2012 Visual Studio Authoring Extensions (32 mo) : http://www.microsoft.com/en-us/download/details.aspx?id=30169

Et… c’est tout ! L’installation est des plus classique (suivant -> suivant -> OK) et vous permet d’obtenir un Visual Studio en bonne et due forme, avec les templates nécessaires au développement de Management Packs :

clip_image034

Bon développement !

SCOM 2012 – Repasser des agents en Remotely Manageable

 

Lorsqu’un agent a été installé manuellement, par exemple en raison d’un flux bloqué temporairement ou d’une installation réalisée par une personne peu habituée à utiliser SCOM, cet agent se retrouve impossible à gérer de façon centralisée depuis la console :

clip_image002

clip_image004

Il n’est malheureusement pas possible de modifier cet état en passant par la console, ni en passant par Powershell ; la seule solution officielle est donc de désinstaller cet agent, puis de le réinstaller en le déployant cette fois depuis la console.

En réalité, cet état est stocké sous forme de « flag » dans la base de données OperationsManager.

La requête SQL suivante permet de lister tous les agents flaggés comme étant « non remotely manageable » :

select bme.DisplayName from MT_HealthService mths

INNER JOIN BaseManagedEntity bme on bme.BaseManagedEntityId = mths.BaseManagedEntityId

where IsManuallyInstalled = 1

clip_image006

On peut donc modifier l’état « non remotely manageable » simplement en passant le flag IsManuallyInstalled de 1 à 0 dans la base de données.

Attention, les modifications en base de données ne sont pas supportées par Microsoft ! Une sauvegarde de la base avant d’y exécuter des requêtes reste toujours vivement recommandé.

  • · Pour modifier le flag sur l’intégralité des serveurs et tous les passer en « Remotely Manageable », on utilise la requête SQL suivante :

UPDATE MT_HealthService
SET IsManuallyInstalled=0
WHERE IsManuallyInstalled=1

  • · Pour modifier le flag sur un unique serveur, on utilise la requête SQL suivante (note : le BaseManagedTypeID AB4C891F-3359-3FB6-0704-075FBFE36710 correspond au HealthService)

UPDATE MT_HealthService
SET IsManuallyInstalled=0
WHERE IsManuallyInstalled=1
AND BaseManagedEntityId IN
(select BaseManagedEntityID from BaseManagedEntity
where BaseManagedTypeId = 'AB4C891F-3359-3FB6-0704-075FBFE36710'
AND DisplayName = 'server.pouet.lan')

En effet, elle contient l’intégralité des serveurs qui s’authentifient par certificat et ces derniers sont dans la majorité des cas des serveurs installés manuellement pour une bonne raison (DMZ etc). Il n’est donc pas souhaitable de les repasser en RemotelyManageable.

Nous allons donc dans un premier temps lister l’ensemble des instances de cette classe à l’aide de powershell (à l’exception des serveurs MS et des gateway, qui sont bien des agents possédant un certificat mais que l’on souhaite gérer de facon centralisée)

Cette liste sera créée sous une forme directement exploitable dans une requête SQL :

$managementservers = Get-SCOMManagementServer | ForEach-Object {$_.displayname}

$certagents = get-scomclassinstance -class (Get-SCOMClass -name "MP_AgentCertificate.Server") | where {$managementservers –notcontains $_.displayname }

foreach ($certagent in $certagents) {"AND DisplayName != '" + $certagent.displayname + "'"}

clip_image008

Il ne reste plus qu’à copier la liste générée (les lignes AND DisplayName != ‘serveurxxx’ ) et à l’intégrer dans la requête SQL précédente :

UPDATE MT_HealthService
SET IsManuallyInstalled=0
WHERE IsManuallyInstalled=1
AND BaseManagedEntityId IN
(select BaseManagedEntityID from BaseManagedEntity
where BaseManagedTypeId = 'AB4C891F-3359-3FB6-0704-075FBFE36710'
AND DisplayName != 'server001'
AND DisplayName != 'server002'
AND DisplayName != 'server003'
AND DisplayName != 'server004'
)

Une fois la requête appropriée exécutée, vos agents devraient apparaitre comme RemotelyManageable dans la console SCOM quasi instantanément (un refresh de la console peut aider si ce n’est pas le cas).

SCOM 2012 – Identifier les agents authentifiés par certificat

Dans une infrastructure SCOM, il arrive couramment qu’une petite partie des agents nécessite une authentification par certificat, la plupart du temps lorsqu’ils sont installés sur des serveurs en DMZ, Workgroup ou sur des serveurs membres de domaines ne disposant pas de relation d’approbation.

De ce fait, ils sont la plupart du temps installés manuellement et non pas déployés depuis la console SCOM.

Ces agents nécessitent une attention particulière, car leur gestion diffère des agents déployés plus traditionnellement : ils nécessitent un renouvellement de certificat à échéance régulière, ils ne peuvent pas être mis à jour automatiquement…

Il n’existe pourtant par défaut pas de classe ni de groupe ni de vue dans SCOM qui permette de les identifier rapidement.

J’ai donc développé une classe pour y remédier. Elle se base sur un script VBS qui tourne toutes les 24h et identifie la présence de la chaine ChannelCertificateSerialNumber dans la clé HKLM\SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\Machine Settings et peuple une classe MP_AgentCertificate.Server basée sur Microsoft.Windows.Computer.

Définition de la classe :

<ClassType ID="MP_AgentCertificate.Server" Accessibility="Internal" Abstract="false" Base="Windows!Microsoft.Windows.Computer" Hosted="false" Singleton="false" Extension="false" />

Définition de la découverte :

<Discovery ID="MP_AgentCertificate.Discovery" Enabled="true" Target="Windows!Microsoft.Windows.Computer" ConfirmDelivery="false" Remotable="true" Priority="Normal">

<Category>Discovery</Category>
<DiscoveryTypes>
<DiscoveryClass TypeID="MP_AgentCertificate.Server" />
</DiscoveryTypes>
<DataSource ID="DS" TypeID="Windows!Microsoft.Windows.TimedScript.DiscoveryProvider">
<IntervalSeconds>86400</IntervalSeconds>
<SyncTime />
<ScriptName>regcertdiscovery.vbs</ScriptName>
<Arguments>$MPElement$ $Target/Id$ $Target/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Arguments>

<ScriptBody>
Dim oAPI
Set oAPI = CreateObject("MOM.ScriptAPI")
Dim oArgs
Set oArgs = WScript.Arguments
' Check for the required script arguments.
if oArgs.Count &lt; 3 Then
' If the script is called without the required arguments,
' create an information event and then quit.
Call oAPI.LogScriptEvent("regcertdiscovery.vbs",101,0,"script was called with fewer than three arguments and was not executed.")
Wscript.Quit -1
End If
Dim SourceID, ManagedEntityId, TargetComputer, strComputer

SourceId = oArgs(0) ' The GUID of the discovery object that launched the script.
ManagedEntityId = oArgs(1) ' The GUID of the computer class targeted by the script.
TargetComputer = oArgs(2) ' The FQDN of the computer targeted by the script.
Dim oDiscoveryData, oInst

Set oDiscoveryData = oAPI.CreateDiscoveryData(0, SourceId, ManagedEntityId)
Const HKEY_LOCAL_MACHINE = &amp;H80000002
strComputer = "."
Set StdOut = WScript.StdOut
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &amp; strComputer &amp; "\root\default:StdRegProv")
strKeyPath = "SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\Machine Settings"
strValueName = "ChannelCertificateSerialNumber"

oReg.GetBinaryValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue

if IsNull(strValue) then
StdOut.WriteLine "no cert found"
Call oAPI.LogScriptEvent("regcertdiscovery.vbs",101,0,"no cert found")

else
Call oAPI.LogScriptEvent("regcertdiscovery.vbs",101,0,"cert found")

' Discovered the application. Create the application instance.

Set oInst = oDiscoveryData.CreateClassInstance("$MPElement[Name='MP_AgentCertificate.Server']$")

' Define the property values for this instance. Available

' properties are determined by the Management Pack that

' defines the class.

Call oInst.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", TargetComputer)
Call oDiscoveryData.AddInstance(oInst)

end if

' Submit the discovery data for processing.

Call oAPI.Return(oDiscoveryData) </ScriptBody>

<TimeoutSeconds>600</TimeoutSeconds>
</DataSource>
</Discovery>

Libre à vous ensuite d’intégrer ces éléments à votre propre MP et d’y ajouter des moniteurs ou de créer une vue listant les instances de la classe MP_AgentCertificate.Server etc.

Note : il peut être utile de créer une override qui exécute cette découverte toutes les 10 minutes dans un premier temps, puis de la supprimer lorsque tous les serveurs sont découverts.

Attention si vous utilisez les instances de cette classe pour effectuer des traitements par lot : elle contient tous les agents possédant un certificat, y compris les MS et les Gateways !

Vous trouverez un exemple d’utilisation de cette classe dans l’article Passer des agents en remotely manageable

SCOM 2012 – Impossible de modifier un UserRole

 

Lors de la modification des propriétés d’un User Role (par exemple un changement dans le Scope), le message Parameter UserRoleDisplayName cannot be null apparait au moment de sauvegarder ces changements.

clip_image002

Bien entendu, dans la console SCOM, le champ « user role name » n’est pas vide.

A quoi peut donc être due cette erreur ?

Allons faire un tour dans la base de données, là où sont stockées les localisations :

clip_image004

select LanguageCode,LTValue from LocalizedText

where LTValue like ('operations manager %operators')

On remarque immédiatement que le rôle qui nous pose problème (ici Operations Manager Report Operators, mais cela pourrait être n’importe quel role créé après l’installation) comporte un LanguageCode différent, qui correspond normalement à la langue du système depuis lequel a été créé ce role.

On en déduit donc rapidement qu’un rôle créé depuis une console SCOM installée localement sur votre poste personnel (et dont le Windows est en général en francais) prend le LanguageCode correspondant à ce système et devient impossible à modifier depuis une console installée sur un système localisé dans une autre langue, par exemple depuis la console installée sur le serveur SCOM qui est généralement lui en anglais !

En attendant que Microsoft corrige ce problème, les contournements possibles sont assez évidents :

  • Utiliser une console installée sur un Windows localisé dans la même langue que celle qui a servi à créer le rôle
  • Modifier le champ LanguageCode des rôles problématiques afin de les passer en ENU. Notez cependant que Microsoft ne fournit pas de support si vous effectuez des modifications manuelles en base de données en dehors de leurs propres instructions.

SCOM - Modifier la criticité d’une alerte Exchange

Modifier la sévérité d’une alerte est une problématique qui peut sembler des plus basique dans le suivi d’une infrastructure SCOM, mais pour laquelle il est utile de préciser quelques subtilités lorsqu’il s’agit du management pack Exchange 2010 et de son correlation engine.

Comme vous ne l’ignorez probablement pas, le fonctionnement de ce management pack est particulier : la génération d’alertes repose sur un service externe, le correlation engine, qui s’occupe d’agréger toutes les remontées d’erreur afin d’en générer une seule alerte la plus pertinente possible.

clip_image002

Première subtilité : si pour créer votre override vous cliquez directement sur le champ Alert Rule contenant le nom de la règle KHI […], puis allez dans l’onglet Overrides et faites un Override > For all of Objects of Class […], cette dernière sera incorrecte.

Cette procédure est parfaitement valable en temps normal, mais pas ici. En effet, l’override doit être créée pour le serveur d’où provient réellement l’alarme, c'est-à-dire celui qui exécute le Correlation Engine, donc le RMS (ou RMS Emulator sous SCOM 2012). Or, par défaut la procédure mentionnée va cibler le rôle d’où l’alerte est supposée provenir, c'est-à-dire OWA dans notre exemple :

clip_image004

Il est donc ici nécessaire de créer l’override For all objects of another class, et de sélectionner la classe RMS (ou RMS Emulator sous SCOM 2012) :

clip_image006

Voilà déjà un écueil évité.

Seconde subtilité : une fois arrivé à l’écran de création de l’override à proprement parler, vous pouvez être surpris par la valeur par défaut du paramètre Severity, traditionnellement utilisé pour modifier la criticité d’une alerte. C’est là aussi dû au Correlation Engine.

clip_image008

Mais ne vous laissez pas impressionner par cette longue variable : il suffit d’indiquer en valeur d’override 0, 1 ou 2 selon la criticité souhaitée (info, warning, critical) !

N’oubliez pas d’enregistrer cet override dans un management pack dédié à Exchange.