PI Services

Le blog des collaborateurs de PI Services

Orchestrator – Problème d’affichage de runbook

 

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

Pour débuguer ce problème:

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

- Exécutez la requête suivante:

Use Orchestrator

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

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

 

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

Use Orchestrator

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

Office 2013 - Personnalisation du ruban d’Outlook via GPO

Contexte

Suite au déploiement de Lync Server 2013, certains clients souhaitent améliorer la visibilité du produit au sein d’Outlook en rajoutant une icône dans la page d’accueil Outlook (par défaut pour créer une réunion Lync, il faut aller dans la partie calendrier).

Problématique

Cette personnalisation d’Outlook n’existe pas dans les modèles d’administration / personnalisation  d’Office (http://www.microsoft.com/en-us/download/details.aspx?id=35554). Cependant il est possible de déployer ce paramètre par GPO.

Solution

N.B : Cette solution a été testée sous Outlook 2010 et 2013.

Lors de la personnalisation du ruban d’Outlook ce dernier créer le fichier olkexplorer.officeUI. Ce fichier se trouve à l’emplacement suivant :

  • Sous Windows XP : %Userprofile%\Local Settings\Application Data\Microsoft\Office\
  • Sous Windows 7/8/8.1 :  %userprofile%\AppData\Local\Microsoft\Office\

Il suffit alors de personnaliser le ruban depuis un poste et de récupérer le fichier olkexplorer.officeUI.

Le déploiement du fichier se fait ensuite via un script lancé au démarrage du poste via GPO.

1 ver | find /i "version 5.1." > nul 2 if %errorlevel%==0 (goto xp) else (goto seven) 3 4 :xp 5 copy \\SERVEUR\Partage\Scripts\WinXP\olkexplorer.officeUI "%Userprofile%\Local Settings\Application Data\Microsoft\Office\" 6 goto logxp 7 8 :seven 9 robocopy /s /e \\SERVEUR\Partage\Scripts\Win7\ %Userprofile%\AppData\Local\Microsoft\Office\ 10 goto logseven 11 12 :logxp 13 FOR /F "usebackq" %%i IN (`hostname`) DO SET MYVAR=%%i 14 if exist "%Userprofile%\Local Settings\Application Data\Microsoft\Office\olkexplorer.officeUI" (goto OKXP) else (goto KOXP) 15 16 :OKXP 17 echo %date% -- Custom Office OK >> \\SERVEUR\Partage\LOG\result.%MYVAR%.txt 18 goto end 19 20 :KOXP 21 echo %date% -- Custom Office FAILED >> \\SERVEUR\Partage\LOG\result.%MYVAR%.txt 22 goto end 23 24 :logseven 25 FOR /F "usebackq" %%i IN (`hostname`) DO SET MYVAR=%%i 26 if exist %Userprofile%\AppData\Local\Microsoft\Office\olkexplorer.officeUI (goto OKSEVEN) else (goto KOSEVEN) 27 28 :OKSEVEN 29 echo %date% -- Custom Office OK >> \\SERVEUR\Partage\LOG\result.%MYVAR%.txt 30 goto end 31 32 :KOSEVEN 33 echo %date% -- Custom Office FAILED >> \\SERVEUR\Partage\LOG\result.%MYVAR%.txt 34 goto end 35 36 :end 37 38

Avant :2014-06-18_172950

Après : 2014-06-18_173159

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.

Powershell : Introduction à la gestion d'événements

Introduction

Le thème abordé est la gestion d'événements sous Powershell. Il s'agit d'une notion peu connue dans ce langage de scripting mais permettant d'interagir automatiquement avec le système si un événement est détecté. Ceux-ci peuvent être : 

  • Le démarrage d'un process
  • Un changement sur un dossier
  • La fin d'un timer
  • Un changement d'état dans un job Powershell
  • ...

Dans un premier, nous verrons comment connaître les objets pouvant être observés et comment gérer les événements via la Cmdlet Register-ObjectEvent, ensuite nous traiterons le cas particulier des événements WMI, puis celui des événements liés à la console Powershell. Enfin, un exemple d'utilisation sera montré (détection des changements dans un dossier).

Avant de débuter, il faut savoir que les événéments gérés, ne le sont que dans la session Powershell en cours (c'est à dire que la remontée d'événements s'arrête dès qu'on quitte la session Powershell). Il existe toutefois une méthode pour créer une gestion d'événements permanente, mais elle ne fonctionne que pour les événements en WMI. Pour faciliter sa mise en place, je vous invite à vous tourner vers l'excellent module PowerEvents : http://powerevents.codeplex.com/.

Les événements des objets Powershell

Pour connaître si un objet Powershell peut être géré via des événements, il suffit d'utiliser la commande Get-Member.

En exécutant la commande suivante :

 

Il est aussi possible de les obtenir via la méthode GetEvents :

 

On obtient le résultat :

image

On remarque que 2 de ces membres sont de type Event (Elapsed et disposed). Ces derniers vont donc pouvoir être utilisé via la cmdlet Register-ObjectEvent.

Exemple pour l’événement Elapsed (fin d’un timer) :

Lorsque l'on lance cette commande, elle crée un job Powershell (similaire à ceux lancés par la commande Start-Job). Dans cet exemple nous voulons monitorer la fin d'un timer pour récupérer les données transmises par un job Powershell à chaque seconde. On crée un objet de type Timer qui a un interval de 1 seconde (en millisecondes). Ce dernier tourne en boucle grâce à l'attribut autoreset. L'événements à surveiller est "Elapsed". On le retrouve dans la commande Register-ObjectEvent avec le paramètre EventName. Le paramètre Action définit le processus exécuté lorsque l'événment est détecté. Il s'agit d'un scriptblock (entre accolades, ici notre variable “ActionTimer”).

Il est possible de passer des données pour qu'elles soient traiter dans l'action. Cela se fait via le paramètre MessageData (N'importe quel type d'objet peut être consommé). Ces données sont ensuite accessible via la variable $event.MessageData. Nous récupérons donc la propriété Id de l'objet Job Powershell afin de recevoir les données via la commande Receive-Job. Pour que l'événement soit remonté , il est obligatoire de fournir l'objet Timer en tant qu'InputObject. Enfin, SourceIdentifier est simplement le nom du job.

Si l'on souhaite arrêter d'observer les événements d'un objet Powershell, il faut utiliser la commande Unregister-ObjectEvent conjointement à Get-EventSubscriber qui récupère l'ensemble des événements observés.

 

Cette commande arrête la remontée de tous les événements. On peut bien entendu filtrer les événements à ne plus gérer via la cmdlet Where-Object par exemple.

Les événements en WMI

En WMI, il existe de nombreuses classes WMI permettant la gestion d'événements. Pour toutes les récupérer et retrouver celle qui vous intéresse, utilisez cette commande :
 

On remarque entre autre des classes pour récupérer :

  • les changements dans les clés de registre
  • les démarrages et arrêts de processus
  • l'arrêt ou la fermeture de session d'un utilisateur
  • l'ajout d'un lecteur (disque dur, clé usb)
  • ...

Pour surveiller un événements en WMI on utilise cette fois la commande Register-WMIEvent.

Exemple de détection de lancement d'un nouveau processus :

La requête effectue une recherche toutes les 2 secondes sur la classe __InstanceCreationEvent. Elle est basé sur le langage WQL dont on peut retrouvé la syntaxe sur le lien suivant :
http://msdn.microsoft.com/en-us/library/windows/desktop/aa394606(v=vs.85).aspx

On retrouve les paramètres sourceIdentifier et Action vues précédemment avec la commande Register-ObjectEvent.

Les événements de la console Powershell

On peux écouter deux événements sur la console Powershell. Lorsqu'elle est fermée (Exiting) et lorsqu'elle est en état Idle (OnIdle). Ainsi, on peut exécuter des actions quand l'un de ces états est atteint. Cette opération s'effectue via la commande Register-EngineEvent :

 

La syntaxe est semblable à celle de la commande Register-ObjectEvent sauf que c'est le paramètre SourceIdentifier qui contient le non de l'événement (on aura donc 2 SourceIdentifier possibles : Powershell.Exiting et Powershell.OnIdle).

NB : Depuis Powershell 3.0, un troisième événement semble exister : WorkflowJobStartEvent. Cependant, il n'est à l'heure actuelle (au 23/05/2014) pas documenté.

Exemple d'utilisation :

Le script commenté ci-dessous déplace les fichiers d'un répertoire à un autre lorsqu'un nouveau fichier apparaît. Un premier événement sur l'objet de type FileSystemWatcher est récupéré : Created. Lors de la remontée de cet événement (à chaque création de fichier) le chemin du fichier est retourné. Un second objet de type Timer est surveillé. A chaque seconde, il récupère les résultats du Job précédent (les chemins de fichiers). Il les ajoute à une liste puis il traîte cette liste en essayant de déplacer les fichiers. Deux résultats sont alors possibles :

  • Si le transfert réussi, alors le chemin initial est supprimé de la liste des fichiers à transférer.
  • Si le déplacement échoue (fichier en cours d'écriture par exemple) alors il retentera de le déplacer au prochain déclenchement de l'événement (après 60 tentatives le transfert n'est plus réalisé).

Les différentes opérations sont logguées dans l'observateur d'événements.

NB : Si le fichier existe déjà à la destination, un horodatage est ajouté en suffixe du nom du fichier.

Desired State Configuration (Partie 4) : Configuration du mode pull (via web service)

Introduction

Cet article fait partie d’une série de 5 billets sur Desired State Configuration :

Desired State Configuration est disponible comme Powershell 4.0 sur Windows 2012 R2/8.1, Windows 2012/8 et Windows 2008 R2/7.

Lors du précédent article nous avons vu le fonctionnement du mode Pull puis son implémentation. Cette dernière se base sur un partage SMB permettant à tous les clients d'aller récupérer leur configuration par ce biais.

Dans cette quatrième partie, nous aborderons l'implémentation du mode Pull via un web service.

Fonctionnement

Le fonctionnement du mode Pull est expliqué dans la Partie 2 de ce guide sur DSC. Dans le mode Pull via web services, seul la façon de publier les fichiers de configurations et l'implémentation changent. Au lieu d'utiliser un partage, les clients DSC interrogerons à intervalle régulier une URL pour récupérer leur configuration :
http://PullServerName:8080/PSDSCPullServer/PSDSCPullServer.svc" où PullServerName représente le nom du serveur Pull.

Contrairement au mode Pull via partage SMB, il n'est possible de déployer le Web Services que sur une version Serveur de Windows. Celui-ci se base sur la fonctionnalité Windows Powershell Desired State Configuration Service. Cependant, via le web service, il est possible de sécuriser la connexion avec l'usage de certificat.

Nous retrouvons les mêmes étapes que pour un serveur Pull via partage. Les clients ont un GUID unique de configuration. Ils récupèrent le fichier .mof portant ce GUID. Une vérification d'intégrité du fichier est effectuée grâce à un fichier portant le même GUID avec l'extension .mof.checksum.

Implémentation du web service

Dans cette section, j'explique comment mettre en place un serveur Pull avec Web Service de façon manuelle afin de comprendre les différentes briques de cette fonctionnalité. Dans le dernier paragraphe, vous trouverez des liens vers des ressources Desired State Configuration permettant de réaliser toute cette configuration beaucoup plus rapidement.

Tout d'abord, on installe le service DSC en graphique ou via la commande :

Install DSC Service

Toute une série de dépendance est ainsi installée dont notamment IIS et le Windows Process Activation Service.

Capture d_écran 2014-04-20 à 11.52.16

Puis dans IIS, on crée un nouveau pool d'application (DSCApplicationPool) qui sera lancé avec le compte Local System (Sur le pool d’application choisir “Advanced Settings” puis “Identity”).

Add PoolConfigure Pool

On crée un nouveau site (Exemple : DSCPullSite) utilisant notre pool d’application nouvellement créé et on le fait pointer vers un dossier de son choix. Ce dernier contiendra les sources du web service.

Add Site

Dans le dossier du site web IIS, on crée un répertoire bin dans lequel on copie le fichier Microsoft.Powershell.DesiredStateConfiguration.Service.dll contenu dans $pshome/modules/psdesiredstateconfiguration/pullserver ($pshome correpond à C:\Windows\System32\WindowsPowerShell\v1.0 si vous avez une installation classique de Windows). 

Il faut ensuite copier les fichiers suivants contenu dans le dossier  $pshome/modules/psdesiredstateconfiguration/pullserver à la racine du site web :

  • Global.asax 
  • PSDSCPullServer.mof 
  • PSDSCPullServer.svc 
  • PSDSCPullServer.xml 
  • PSDSCPullServer.config : il doit être renommé en web.config

L'arborescence doit être identique à celle ci-dessous :

Arborscence

Il faut ensuite autoriser les différentes méthodes d'authentification en réalisant un "unlock" sur les sections adéquate du fichier web.config que nous avons copié (anciennement PSDSCPullServer.config).

Voici un script permettant de réaliser cette opération :

Le résultat peut être vérifié dans le fichier C:\Windows\System32\inetsrv\config\applicationHost.config 

web.config

Enfin, dans ce même fichier web.config il faut ajouter les lignes suivantes dans le noeud appsettings :

Lors de l'installation du service DSC, une hiérarchie de dossier a été créée dans C:\Program Files\WindowsPowerShell\DscService :

  • Configuration : dans ce dossier, il faut placer les fichiers .mof et .mof.checksum (renommé avec un GUID, voir Partie 2).
  • Modules : Contient les éventuels modules dont on pourrait avoir besoin.

Pour terminer la configuration du serveur Pull, il faut copier le fichier $pshome/modules/psdesiredstateconfiguration/pullserver/Devices.mdb vers le dossier C:\Program Files\WindowsPowerShell\DscService

L'url du web service (http://PullServerName/PSDSCPullServer.svc) est maintenant opérationnelle !

Ressource LocalConfigurationManager

La ressource LocalConfigurationManager (déjà rencontrée dans les autres articles sur DSC) doit être configurée pour utiliser le web service.

Cette configuration est similaire à celle de la Partie 2 et 3. On retrouve le ConfigurationID permettant de récupérer les bons fichiers .mof. Les paramètres à changer sont :

  • DownloadManagerName : Il prend la valeur WebDownloadManager. 
    DownloadManagerCustomData : Il contient un hashtable avec l'url du web service et un second paramètre AllowUnsecureConnection utile si vous n'utilisez pas de certificat.
Voici une configuration d'exemple :

Annexe

Depuis la sortie de Powershell V4.0, Microsoft s'est employé à fournir de nombreuses nouvelles ressources pour DSC. Celles-ci sont disponibles en suivant le lien ci-dessous :
http://gallery.technet.microsoft.com/scriptcenter/DSC-Resource-Kit-All-c449312d

Ces ressources sont précédées d'un "x" car elles sont encore considérées comme expérimentales. Parmis toutes ces nouvelles ressources (plus d'une cinquantaine !), il y en a une pour déployer un server Pull facilement (xDscWebService). Cette dernière permet d'effectuer toutes les opérations fastidieuses que l'on a mis en place dans la section précédente (création d'un pool d'application, d'un site web, copie des différents fichiers,...).

Voici un exemple d'utilisation de cette ressource :

On retrouve les paramètres tel que le nom du pool d'application (EndpointName), le chemin vers le site web (PhysicalPath),... Cela nous permet aussi de pouvoir customiser simplement les chemins qui vont contenir nos fichiers .mof et .mof.checksum ainsi que les ports utilisés par DSC et l'intégration d'un certificat.

Vérifier l’installation d’un KB sur plusieurs serveurs

Contexte

Dans certains cas, il faut déployer un patch Microsoft sur plusieurs serveurs. Mais comment savoir simplement et rapidement si le patch est bien installé, surtout si vous ne disposez pas de la solution System Center ?

Tout simplement avec un script Powershell. Voyons comment faire.

Dans mon exemple ci dessous, je veux savoir si un KB est installé sur tous les contrôleurs de domaine de tous les domaines de toute ma forêt Active Directory.

Compatibilité

Tout d’abord, ce script s’appuie sur des cmdlets (Get-Job et Get-Hotfix notamment) qui ne sont disponibles qu’avec Powershell version 2 minimum. Pensez à vérifier votre version de Powershell.

Fonctionnement

Dans un premier temps, il faut passer le paramètre “hotfix” au script.

Lors du lancement du script, voici les étapes :

  1. 1- Vérification de la syntaxe du paramètre. Il doit être au format “KBxxxxxx”.
  2. 2- Récupération de la liste de tous les domaines de la forêt Active Directory.
  3. 3- Interroge Active Directory pour récupérer la liste des contrôleurs de domaines en demandant les membres du groupe 'Domain Controllers' pour chaque domaine.
  4. 4- Récupération des identifiants pour se connecter à tous les DC.
  5. 5- Création des jobs, avec un job par serveur et maximum 15 jobs simultanés (paramètre $MaxThreads ligne 9).
  6. 6- Récupération des résultats des jobs.
  7. 7- Affichage d'un résumé.
  8. 8- Exportation des résultats.

 

Les jobs Powershell sont utilisés ici afin d’augmenter la rapidité d’exécution. Sinon, les serveurs serait interrogés les uns après les autres. Cette solution fonctionne tout aussi bien, mais demande beaucoup de temps. L’intérêt des jobs est de pouvoir lancer plusieurs requêtes en parallèle. Toutefois, attention à la consommation mémoire car il y’a autant de processus Powershell en mémoire, qu’il y’a de jobs.

Script

Utilisation

Il faut sauvegarder le script ci dessus avec le nom “Check_Hotfix_Installation.ps1”. Ensuite il suffit d’appeler le script dans une console Powershell (en Administrateur) comme ceci : “Check_Hotfix_Installation –Hotfix KB2413670

Conclusion

Avec un simple script Powershell et l’utilisation des jobs, on peut vérifier énormément de serveurs et très rapidement. Rien empêche de modifier le script pour déclencher l’installation du hotfix avant la vérification, ou encore de cibler des serveurs plutôt que des contrôleurs de domaine.

Libre à vous d’adapter ce script selon vos besoins !

Powershell V5 Preview est sorti ! DSC, Switch, OneGet et du chocolat.

Introduction

Après le Management Framework 4.0 qui apportait Desired State Configuration, la Powershell Team vient de publier Management Framework 5.0 Preview (le 03/04/2014). Cette nouvelle version intervient seulement 6 mois après la sortie de la V4.0. Microsoft accélère son cycle de développement avec des versions contenant moins de nouveautés mais celles-ci restent tout de même importantes.

Le Management Framework 5.0 est pour l'instant compatible uniquement avec Windows Server 2012 R2, Windows 8.1 Pro et Enterprise mais Microsoft parle d'une rétrocompatibilité avec d'autres versions à venir.

Voici le lien vers l'update a installé :
http://www.microsoft.com/en-us/download/details.aspx?id=42316

Il contient Powershell V5.0 et Powershell ISE.

Capture d’écran 2014-04-17 à 19.00.43

Il est temps de faire le tour des nouveautés !

Générales

Comme à chaque nouvelle version de Powershell, on nous annonce moins de bugs, de meilleures performances et des nouvelles Cmdlets.

Desired State Configuration

Des corrections de bug et des améliorations de performances sont au programme. La Team Powershell indique que Desired State Configuration est une technologie importante pour eux. C'est logique quand on voit le nombre de ressources (plus de 50) qui a été développé depuis la sortie de Powershell V4.0 : http://blogs.msdn.com/b/powershell/archive/2014/03/28/dsc-resource-kit-wave-3.aspx . Ils indiquent que la stratégie de Microsoft est de pousser l'intégration de DSC avec les outils de gestion de configuration (SCCM ?) et que lors d'un choix de ce type de solution, il sera important qu'elle soit compatible avec DSC.

Switch

Powershell V5.0 propose un module natif permettant de manipuler ses switchs. Microsoft a travaillé avec les leaders de l'industrie afin d'élaborer un standard. Les équipements compatibles porteront la certification "Certified for Windows". Au delà de Powershell, ce standard est utilisé dans SCVMM 2012. Cette technologie fait partie de la politique "Datacenter Abstraction Layer" de Microsoft. Elle vise à gérer l'intégralité d'un Datacenter via un même outil de management au lieu d'avoir une vision réduite à un équipement. Elle permettra d'éviter la multiplication des outils de gestion.

Le module qui permet de manipuler les switchs est : NetworkSwitch. Pour être compatible avec ce standard, le switch devra supporté les sessions distantes CIM. Pour rappel, c'est un standard ouvert développé par la DMTF (Distributed Management Task Force) qui définit les interractions entre des équipements ainsi que leur gestion, supervision, etc sous la forme d'un schéma. Ce schéma est orienté objet. WMI est notamment compatible avec ce standard (depuis Powershell V3.0 via les Cmdlets comme Get-CIMClass, Set-CIMInstance, ...).

Voici la liste des commandes de ce module :

Capture d’écran 2014-04-17 à 19.07.54

Parmi les fonctionnalités, il est ainsi possible de :

  • réaliser la configuration générale du switch : nom d’hôte, bannière, activation/désactivation de fonctionnalités
  • gérer les vlan : création, suppression, activation, désactivation, listing
  • configurer les ports : activation, désactivation, listing, définition des propriétés

OneGet

On termine ce tour des nouveautés, avec la fonctionnalité qui va sans doute faire le plus parlée d'elle : OneGet. C'est tout simplement un gestionnaire de paquet comme on peut en rencontrer sur Unix !

Pour obtenir la liste des commandes disponibles :

Capture d’écran 2014-04-17 à 19.07.16

On peut utiliser la commande Find-Package pour chercher 7zip par exemple :

Capture d’écran 2014-04-17 à 19.14.18

Puis-on l'installe (Install-Package) :

Capture d’écran 2014-04-17 à 19.14.36

Bien entendu, comme tout gestionnaire de paquet, il s’occupe également d’installer automatiquement les dépendances.

La commande Get-Package permet de récupérer les packages déjà installé. Le package apparaît dorénavant dans le Start Screen (ou dans Program Files) comme n’importe quel autre programme :

Capture d’écran 2014-04-17 à 19.16.11

Dans cette version preview, OneGet ne possède qu'une seule source (ou repository) : Chocolatey (https://chocolatey.org/packages) qui contient actuellement plus de 1700 package. Ce dernier est basé sur NuGet (connu des utilisateurs de Visual Studio) qui est justement un gestionnaire de package. Microsoft ajoutera le support d'autres repositories ultérieurement. On peut même imaginer qu'il sera possible de créer sa propre source et de l'ajouter via la commande Add-PackageSource. Certaines personnes ont d'ailleurs déjà commencé à le faire : http://learn-powershell.net/2014/04/11/setting-up-a-nuget-feed-for-use-with-oneget/.

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>

 

SQL Server – Amélioration de la reconstruction d’un index en ligne sous SQL Server 2012.

SQL Server 2012 cache quelques petites nouveautés qui peuvent bien vous surprendre.

J’ai découvert récemment qu’il est désormais possible de reconstruction un index en ligne sur SQL Server 2012 de tables qui contiennent des types VARCHAR(MAX) et NVARCHAR(MAX).

Démonstration :

Commencez par exécuter le script sous SQL Server 2008 R2 puis sur SQL Server 2012.

USE [tempdb]
GO
CREATE TABLE T1
(ID INT, C1 NVARCHAR(10), C2 NVARCHAR(MAX))
GO
CREATE CLUSTERED INDEX [IX_T1]
ON T1
(ID)
GO
CREATE NONCLUSTERED INDEX [IX_T1_Cols]
ON T1
(C1)
INCLUDE (C2)
GO
USE [tempdb]
GO
ALTER INDEX [IX_T1_Cols] ON [dbo].[T1]
REBUILD WITH (ONLINE = ON)
GO
DROP TABLE T1
GO

Résultat :

Sur le serveur SQL Server 2008 R2, on a un message d’erreur du type

Msg 2725, Level 16, State 2, Line 1
An online operation cannot be performed for index ‘IX_T1_Cols’ because the index contains column ‘C2’ of data type text, ntext, image, varchar(max), nvarchar(max), varbinary(max), xml, or large CLR type. For a non-clustered index, the column could be an include column of the index. For a clustered index, the column could be any column of the table. If DROP_EXISTING is used, the column could be part of a new or old index. The operation must be performed offline.

Tandis que sur le serveur SQL Server 2012

Command(s) completed successfully.