Windows PowerShellLa connexion WMI

Don Jones

L’une des technologies qui m’a beaucoup servi dans l’univers VBScript est Windows Management Instrumentation ou WMI. Il est intéressant de voir que Windows PowerShell dispose de liens très étroits avec WMI (et pas juste au sens technique). Jeffrey Snover, l’architecte de Windows PowerShell, a également joué un rôle clé dans la création de

Wmic.exe, un outil de ligne de commande de l’ère Windows Server® 2003 à utiliser avec WMI. De bien des façons, Wmic.exe a anticipé la création de Windows PowerShell™, de par le fait qu’il fonctionnait de façon similaire. (Pour plus d’informations sur WMIC, voir l’article de John Kelbley dans le numéro de septembre 2006 de Technet Magazine, disponible en ligne à l’adresse microsoft.com/technet/technetmag/issues/2006/09/WMIData.)

Windows PowerShell prend WMI en charge avec autant de cohérence et la même méthodologie basée sur objet que pour le reste des fonctionnalités du noyau. Ceci facilite considérablement l’apprentissage et l’utilisation de WMI (surtout dans les situations ad hoc) par rapport aux technologies précédentes telles que VBScript.

Introduction à WMI

Si vous lisez des livres et des articles sur le script, il est presque impossible de ne pas voir WMI mentionné. Cependant, il est facile de se perdre dans l’utilisation de WMI au point d’en oublier son fonctionnement en coulisses. En effet, savoir comment WMI est généré est particulièrement important pour comprendre son fonctionnement dans Windows PowerShell.

WMI est principalement un système de classes organisées qui représentent les informations de gestion provenant du système d’exploitation Windows®, ainsi que du matériel et des logiciels basés sur Windows. Une classe n’est vraiment rien de plus qu’une description abstraite des propriétés et des fonctionnalités qu’un certain composant logiciel ou de matériel possède. Par exemple, une classe de disque logique peut décrire un périphérique qui a un numéro de série, une capacité de stockage fixe, une quantité de capacité disponible, etc. Dans le même temps, une classe qui décrit un service Windows peut spécifier que le service a un nom, qu’il peut démarrer et s’arrêter, son état actuel, etc.

Dans WMI, les classes représentent tout ce que WMI peut gérer. Si WMI n’a pas de classe pour un élément particulier, il ne peut pas le gérer. Microsoft décrit les classes WMI fondamentales de Windows sur msdn2.microsoft.com/aa394554.aspx ; d’autres produits (tels que les Internet Information Services, SQL Server™) décrivent leurs classes WMI séparément.

Comme il y a tant de classes, WMI les organise en une hiérarchie d’espaces de noms. Par exemple, l’espace de noms contenant les classes fondamentales de Windows OS s’appelle root\cimv2, tandis que Microsoft IIS 6.0 stocke ses classes dans root\Microsoft­IISv2. Pour plus de commodité, l’espace de noms root\cimv2 est l’espace de noms WMI par défaut, un paramètre partagé avec Windows PowerShell, ce qui facilite l’utilisation de ces classes fondamentales.

Une « instance » est une occurrence véritable et réelle d’une classe. Si, par exemple, votre ordinateur a deux disques logiques, vous aurez deux instances de la classe Win32_LogicalDisk. Si vous avez 50 services qui s’exécutent sur votre ordinateur, WMI verra 50 instances de la classe Win32_Service. L’utilisation de WMI consiste essentiellement à lui demander de vous donner une ou plusieurs instances, puis d’en examiner les propriétés pour trouver les informations de gestion dont vous avez besoin ou d’en exécuter les méthodes pour effectuer des modifications de gestion, telles que le démarrage ou l’arrêt d’un service.

WMI fait appel à une architecture client-serveur. Depuis Windows 2000, WMI est intégré à toutes les versions de Windows (les versions ultérieures ont étendu le nombre de classes disponibles), ce qui veut dire que le client WMI et le logiciel de serveur WMI sont tous deux disponibles. Lorsque vous utilisez WMI, vous envoyez une requête au Service WMI qui s’exécute sur l’ordinateur qui vous intéresse. Ce Service WMI récupère les instances WMI que vous spécifiez et vous les retourne pour que vous puissiez les utiliser. C’est là que Windows PowerShell entre en scène : il simplifie le processus de demande, de retour et d’utilisation des instances.

Obtention d’un objet WMI

Les instances de classe WMI sont vaguement appelées des objets. Il est donc sensé de voir que c’est le cmdlet Get-WMIObject qui récupère ces instances dans Windows PowerShell. Ce cmdlet a un alias pratique, gwmi, que j’utiliserai dans la plupart de mes exemples. Dans sa forme la plus simple, il vous suffit de spécifier le nom de la classe WMI que vous voulez récupérer. Ensuite, détendez-vous et contemplez les résultats (voir la figure 1). Lorsque j’ai exécuté gwmi win32_service, Windows PowerShell s’est connecté au service WMI sur mon ordinateur local (puisque je n’avais pas spécifié d’autre ordinateur), puis à l’espace de noms root\cimv2 (car je n’avais pas spécifié un espace de noms différent). Windows PowerShell a récupéré toutes les instances de la classe spécifiée et, puisque je ne lui avais pas indiqué de faire quoique ce soit d’autre avec, les a converties en représentation textuelle. En d’autres termes, Windows PowerShell a pris ces objets et a produit du texte que je pouvais, en tant qu’être humain, lire.

Figure 1 En exécutant gwmi win32_service, Windows PowerShell renvoie toutes les instances de la classe spécifiée dans un format de texte lisible.

Figure 1** En exécutant gwmi win32_service, Windows PowerShell renvoie toutes les instances de la classe spécifiée dans un format de texte lisible. **

Windows PowerShell convertit en particulier les objets WMI en texte en liant et en affichant les noms et les valeurs des propriétés de la classe sélectionnée. Pour la classe Win32_Service, il sélectionne une série de six propriétés.

En fait, Windows PowerShell convertit de cette façon n’importe quel objet en texte. Les propriétés qu’il choisit d’afficher sont, pour la plupart, définies dans un ensemble de fichiers .format.ps1xml situés dans le dossier d’installation de Windows PowerShell. Ces fichiers de définition du format sont numériquement signés par Microsoft. Il vous est recommandé de ne pas modifier ces fichiers, bien que vous puissiez fournir vos propres fichiers de formatage. (Je traiterai ce sujet plus en détails dans une prochaine rubrique.)

Le cmdlet gwmi peut vous aider à explorer votre ordinateur pour trouver les classes disponibles. Par exemple, si vous exécutez gwmi –namespace "root\cimv2" –list, vous obtiendrez une liste complète des classes de cet espace de noms. Cependant, n’oubliez pas que les classes de votre ordinateur ne sont pertinentes que si vous gérez votre ordinateur ; si vous gérez un ordinateur distant, il vous faudra trouver les classes disponibles de ce système. C’est pour cela qu’il est préférable d’utiliser le paramètre informatique du gwmi pour se connecter à un ordinateur distant. Par exemple, gwmi –namespace "root\cimv2" –list –computer ServerA listera toutes les classes de l’espace de noms root\cimv2 sur l’ordinateur distant appelé ServerA.

WMI distant

Dans la version 1.0 de Windows PowerShell, gwmi est à peu près le seul cmdlet qui prend directement en charge la gestion à distance. Ceci est principalement dû au fait que ce contrôle à distance est intégré à l’architecture WMI sous-jacente. De plus, parce que Windows PowerShell n’utilise que cette architecture existante, il est sujet aux fonctionnalités de sécurité de cette dernière. Voici un exemple :

C:\> gwmi -namespace “root\cimv2” -computer
mediaserver -list
Get-WmiObject : Access is denied. (Exception
from HRESULT: 0x80070005 (E_ACCESSDENIED))
At line:1 char:5
+ gwmi <<<< -namespace “root\cimv2” -computer
mediaserver -list
PS C:\>

Dans cette instance, j’ai essayé de me connecter à un ordinateur distant (Media Server) dont l’accès m’est interdit. En tant qu’administrateur, je devrais avoir l’autorisation de travailler avec le service WMI de cet ordinateur, mais il se peut que les informations d’authentification de mon poste de travail local ne soient pas suffisantes. Je pourrais, par exemple, avoir ouvert une session sur un domaine différent et douteux, ou je pourrais avoir ouvert une session sur un compte moins privilégié. Heureusement, gwmi prend en charge un paramètre d’informations d’authentification qui m’autorise à spécifier un ensemble alternatif d’informations d’identification de l’utilisateur pour ma connexion à WMI. Ci-dessous, vous en verrez un exemple très simple :

gwmi win32_service –credential mydomain\administrator –computer mediaserver

Mes informations d’authentification (en particulier, mon nom d’utilisateur) sont fournies au format DOMAIN\Username.

Notez que vous ne pouvez saisir de mot de passe nulle part (Windows PowerShell m’y invitera). Windows PowerShell ne fournit, de façon délibérée, aucun moyen pour saisir un mot de passe sur la ligne de commande, car ce faire vous permettrait de coder en dur des mots de passe en fichiers de script, ce qui représente un très grand risque en matière de sécurité. Cependant, il existe une autre façon d’utiliser ce paramètre d’informations d’authentification : en créant une sorte d’objet d’informations d’authentification, appelé PSCredential, à l’avance. La clé ici est le cmdlet Get-Credential :

$cred = get-credential mydomain\administrator

Lorsque je l’exécute, l’ordinateur m’invite encore à donner le mot de passe correspondant. Cette fois, cependant, l’objet d’informations d’authentification créé est stocké dans la variable $cred. Si je regarde le contenu de $cred, je verrai le nom mais pas le mot de passe :

PS C:\> $cred

UserName
--------
mydomain\adminstrator

Je peux ensuite réutiliser cet objet d’informations d’authentification autant que je le souhaite :

gwmi win32_service –credential $cred –computer mediaserver

Ceci simplifie les connexions WMI répétées à un ordinateur distant par la prédéfinition d’un objet d’informations d’authentification réutilisable. Cependant, il convient de noter que le cmdlet Get-WMIObject ne prend pas actuellement en charge la spécification des niveaux d’authentification (manipulation également connue sous le nom d’imitation) de la même façon que VBScript. Voir msdn2.microsoft.com/aa389290.aspx pour plus d’informations.

Auto-découverte

L’une des choses que je préfère avec Windows PowerShell est qu’il ne simplifie pas les choses à outrance. Je vous ai montré comment Windows PowerShell sélectionnait seulement un ensemble de propriétés pour la classe Win32_Service que j’interrogeais. Le noyau a cependant toujours accès à toutes les propriétés et peut même vous dire ce qu’elles sont. Pour ce faire, il vous suffit de canaliser le ou les objets vers le cmdlet Get-Member (ou son alias, gm), comme le montre la figure 2.

Figure 2 La canalisation d’un objet vers le cmdlet Get-Member vous indique les méthodes et les propriétés auxquelles vous pouvez accéder.

Figure 2**  La canalisation d’un objet vers le cmdlet Get-Member vous indique les méthodes et les propriétés auxquelles vous pouvez accéder. **(Cliquer sur l'image pour l'agrandir)

Outre les propriétés, le noyau liste également les méthodes disponibles, ce qui veut dire que je n’ai pas forcément besoin de la documentation pour savoir ce que peut faire une classe donnée. Je peux voir que la classe elle-même permet de modifier la configuration d’une instance, mettre un service en pause, arrêter un service, etc.

Pour utiliser ces méthodes ou afficher d’autres propriétés, il est souvent plus facile de mettre les instances dans une variable :

$server = gwmi win32_operatingsystem
$server.reboot()

Cet exemple récupérera la seule instance disponible de la classe Win32_Operating­System (cette classe a seulement une instance par ordinateur) et l’enregistrera dans la variable $server. Il utilisera ensuite cette variable pour accéder à la méthode de redémarrage de l’instance, ce qui fera redémarrer l’ordinateur. Faites-y attention !

Langage de requête riche

Si vous avez utilisé WMI sous VBScript ou une autre technologie, vous êtes probablement habitué à récupérer des instances de classes WMI en utilisant une requête écrite dans WQL, le langage de requête de WMI. Sa syntaxe, apparentée à celle de SQL, facilite la récupération d’instances spécifiques (telles qu’un service particulier) au lieu de toutes les instances d’une classe donnée. Heureusement, gwmi vous permet aussi de spécifier une requête, comme suit :

gwmi –query “select * from win32_service where name=’alerter’”

Cette syntaxe de gwmi (qui a été ajoutée juste avant la sortie officielle de Windows PowerShell) est incroyablement utile et facilite énormément la migration de requêtes WMI complexes que vous pourriez avoir développées à d’autres fins. Et, comme toujours, Windows PowerShell renverra des objets riches avec leurs propres propriétés et méthodes, vous offrant un accès complet à la puissance de gestion de WMI.

Poursuivre sa lancée avec WMI

WMI continue d’être développé pour les versions futures de Windows, ce qui se traduit par l’ajout de nouvelles classes et de nouvelles fonctionnalités. Il est en outre de plus en plus souvent accolé aux nouveaux produits Microsoft. Si les versions de la plupart des produits Microsoft intégrées spécifiquement à Windows PowerShell ne sont pas encore sorties, la capacité de ce système à se connecter à WMI constitue l’un des plus grands avantages qui font de Windows PowerShell un outil si utile aujourd’hui.

J’ai seulement effleuré les capacités de WMI. Cela dit, j’espère que je vous ai donné l’envie d’explorer Windows PowerShell et de découvrir vous-même les fonctionnalités disponibles.

Don Jonesest Directeur des projets et services de SAPIEN Technologies et co-auteur de Windows PowerShell : TFM (SAPIEN Press). Pour contacter Don, rendez-vous sur son site Web à l’adresse suivante : www.ScriptingAnswers.com.

© 2008 Microsoft Corporation et CMP Media, LLC. Tous droits réservés. Toute reproduction, totale ou partielle, est interdite sans autorisation préalable.