WMIC – Vous connaissiez ?

Introduction

Je ressort ce vieux tuto pour ceux qui n’ont pas encore franchi le cap de Powershell 😉 – Il a encore une petite utilité dans certains environnements, tels que sous WinPE 2 ou 3, et au pire il vous permettra de réviser vos classiques.L’objectif de ce document est simple : Démystifier WMI et découvrir la console WMIC (Windows Management Instrumentation “Command-Line”) apparue avec Windows XP ou comment aller plus loin dans l’administration Windows avec un minimum d’effort ?!… (N’est-ce pas une qualité dans ce domaine ?)

Commençons par un peu d’histoire

WMI = Windows Management Instrumentation
De son nom original WBEM = Web Based Enterprise Management (Vous trouverez d’ailleurs les fichiers WMI dans “%windir%\system32\wbem”)
Comme son nom ne l’indique peut être pas, WMI est l’infrastructure de gestion Windows implémentée sur les plateformes NT depuis Windows 2000 sp2 (Eh oui, ce n’est pas nouveau)
Extrêmement riche, cette technologie à longtemps été la chasse gardée des développeurs. Surtout que les outils de gestion étaient peu intuitifs et manquaient de convivialité pour un administrateur, plus habitué à des commandes en ligne et autres “batches”.

Avec Windows 2000, le seul outil livré en standard était le “Testeur WMI” ou WBEMTEST.exe. (et comme beaucoup vous n’aviez probablement pas compris grand-chose de son utilité) – NameSpaces, Classes, Instances, Actualisateur… Bref de quoi décourager les plus entreprenants d’entre nous.Pour ma part, je ne l’ai utilisé que tardivement après avoir exploré le potentiel de WMI par d’autres voies plus sympathiques telles que “WMI Tools”, “Scriptomatic” ou plus récemment “WMI Code Creator”. (Produits Microsoft gratuits 😉 sans compter le langage WSH…

Heureusement Microsoft a pensé à nous, pauvres administrateurs, et depuis Windows XP, fourni une console dédiée à la gestion de WMI. Bien que trop méconnue à mon avis, la console WMIC offre un accès par “alias” (noms conviviaux) à tout le potentiel de cette technologie (sous réserve d’en connaître quelques fondamentaux)

Pour faire simple, “WMI” est basé sur un service “winmgmt” ou “Infrastructure de gestion Windows” et une base de donnée d’objets (classes) décrite au travers de fichiers .MOF (Aie !…) NE soyez PAS effrayé, je ne m’aventure pas dans les méandres du développement – Il est tout à fait possible gérer Windows via WMI sans connaître toute la subtilité des objets complexes qu’il utilise, mais un minimum de concepts et de vocabulaire s’impose.

Voici donc un brin de vocabulaire, histoire de comprendre la suite

En gros, on pourrait résumer l’es concepts WMI comme ceci :
Les objets –ce sont des “trucs” plus ou moins complexes qui ont pour noble objectif de vous simplifier la vie. En bref une fonction que vous sollicitez en lui donnant (ou pas) des informations et qui effectuent une action ou vous renvoie un résultat.
Les classes –ce sont les “plans de montage” d’un objet. (Comme pour l’architecture en bâtiment)
Les instances –ce sont les objets “fabriqués” à partir de ces fameux plans de montage (Les immeubles, la maisons…)
Les propriétés –une information particulière de l’objet, comme sa forme, sa taille, …
Les méthodes – une action réalisable par l’objet telle que changer la couleur, bouger, … (Bon, ici l’immeuble n’est plus un bon exemple, mais j’espère que vous me suivez malgré tout)
Les Espaces de nommage (Name Spaces) – un conteneur de rangement des classes (Quant les affaires marchent bien, notre architecte à intérêt de bien ranger ces plans pour s’y retrouver)
Les Requêtes – une demande d’information ou de sélection particulière sur les objets (Peut être que notre architecte, ou nos maçons n’ont pas envie de tout déballer à chaque fois…)

Quelques principes importants
La connexion : Pour utiliser WMI, il faut se “connecter” à la base via des identifiants mais également préciser sur quelle machine* et dans quel espace de nommage. (*Eh oui, l’un des gros atouts de WMI, c’est d’être capable d’interroger les postes à distance – mais j’y reviendrais plus tard, pour le dessert …)

Par défaut, WMI travaille sur le poste local (ou localhost si vous préférez) qui peut être aussi symbolisé par un simple point “.”, son nom d’hôte ou encore une adresse IP.
Pour l’authentification, WMI utilise par défaut les identifiants de l’appelant (la session si vous préférez)
Et enfin, pour les admins, l’espace de nommage le plus riche est ROOT\CIMV2. (pas ROOT\Default comme le propose WBEMTEST !…) – Voila, le décor est planté.

Un mot encore sur la sécurité et les espaces de noms. Vous aviez surement remarqué la rubrique “Contrôle WMI” dans la console de “Gestion de l’ordinateur

Allez dans les propriétés de cette rubrique puis sous l’onglet “Sécurité”…

Voici les fameux conteneurs “NameSpaces”, tous raccrochés à une racine “Root”.

Sélectionnez un conteneur, puis cliquez sur le bouton “Sécurité” afin de voir la liste de contrôle d’accès (ACL)

Remarquez plusieurs choses importantes :
– Les “Administrateurs” ont toutes les autorisations (y compris l’appel à distance) alors que “Tout le monde” est beaucoup moins privilégié.
– Tous les espaces de nommage sont associés à la racine (via le caractère “\”)
– Chaque conteneur “Hérite” des autorisations de la racine, mais les droits d’accès à chaque conteneur, donc aux objets qu’il contient, peut être contrôlé.


La console WMIC

Bien, maintenant on rentre dans le vif du sujet :


En premier lieu sachez que la console WMI s’utilise de 2 manières
– Soit en mode interactif, (WMIC, puis on tape des commandes…)
– Soit en mode ligne (WMIC suivi des commandes)
Personnellement, je préfère cette seconde technique car elle permet de formater les sorties (affichage) et autres subtilités sympathiques que je décrierais plus tard … (Chaque chose en son temps ;-))

WMIC /? vous affiche l’aide simplifiée, “/?:FULL” pour la totale.

Un peu de syntaxe
Les alias, sont les noms conviviaux que Microsoft a affectés aux classes. Par exemple : l’alias ‘OS‘ référence la classe ‘Win32_OperatingSystem‘, l’alias ‘NICConfig‘ référence la classe ‘Win32_NetworkAdapterConfiguration
Vous en voulez un peu plus …

wmic alias get FriendlyName,Target

Vous voulez tout voir, c’est vous qui l’aurez voulu …

wmic alias list

ou avec moins de détails

wmic alias list brief

Pour les plus curieux, vous remarquerez la présence d’une requête “Select *” et d’une clause “Where” qui collecte toutes les instances et contrôle (filtre) les propriétés renvoyées.
Bien, je pense vous aurez compris l’intérêt de l’alias …

On commencera donc notre première commande par un alias suivi d’un “verbe
Les verbes d’interrogation sont GET ou LIST (on ne verra pas tous les verbes, LIST, CALL, GET, SET, ASSOC, CREATE, DELETE)
Le problème, c’est que pour le “GET”, il faut connaître le nom des propriétés (ou attributs) de la classe. Au début, on utilisera plutôt le “LIST” (sous entendu LIST FULL) ou le “LIST BRIEF” pour une énumération épurée (avec le “more” pour éviter le mal de mer ;-).

Astuce : Tapez “/?” Derrière le verbe pour connaître ses paramètres

Ensuite on peut affiner l’affichage en précisant les attributs séparés par des virgules.

wmic service get displayname,state

On continue en affinant notre besoin par la sélection d’instances précises, comme par exemple “rechercher les services dont nom contient le mot “impression”.

wmic service where “displayname like ‘%impression%'” get name,state

C’est un petit peu compliqué, les guillemets encadrent la requête de sélection
Les apostrophes (quotes) encadrent la chaine de caractère à rechercher
Le symbole de pourcentage est un caractère générique remplaçant un ensemble de caractères quelconques (équivalent de l’Astérix dans d’autres mondes ….)
Enfin, l’opérateur “like” pour l’équivalence d’une chaine de caractère mais je vous laisse le soin de les découvrir dans l’aide. (=, >=, AND, etc…)

Allez, on poursuit avec une action car je viens de constater que le service spooler est arrêté. On va donc faire appel à la méthode de l’objet pour le démarrer. On utilise pour cela un verbe d’action “CALL“, ce qui donne :

wmic service where “displayname like ‘%impression%'” call StartService

Rappel d’astuce : Tapez “/?” Derrière le verbe pour connaître ses paramètres

Et voilà, notre service d’impression est démarré, du moins, si le code de retour est à zéro (vous connaissiez le fameux “errorlevel 0”, non ?)

Exécution (\\LEGOLAS\ROOT\CIMV2:Win32_Service.Name=”Spooler”)->startservice()
Méthode exécutée.
Paramètres de sortie:
instance of __PARAMETERS
{
ReturnValue = 0;
};

En fait, vous vouliez tout simplement la liste des services, mais le résultat de votre première commande n’était pas très élégant, non ? Eh bien, là encore, WMIC vous réserve une agréable surprise. Vous pouvez formater votre sortie (résultat) grâce à des feuilles de style (.xsl).
Cette opération s’effectue en ajoutant le commutateur “/FORMAT à la fin de votre commande.

Re-astuce : Tapez “/?” Derrière le commutateur pour connaître ses paramètres

Enfin vous pouvez aussi rediriger vos résultats vers un fichier, ou même le presse-papier (sympathique, non ?). Pour cela consultez le commutateur “/OUTPUT
Ce qui donne au final, pour une sortie vers un joli tableau en HTML

wmic /output:%temp%\listsvc.htm service get displayname, name, state /format:htable

Pour l’afficher, il convient d’invoquer le fichier résultant “%temp%\listsvc.htm”

J’ai gardé le meilleur (à mon sens) pour la fin…
Comme je l’ai mentionné, les commandes WMI interroge par défaut le poste local, mais il est maintenant très facile de solliciter une autre machine (ou plusieurs) à distance. Pour cela, il faut simplement connaître leurs noms ou adresses IP et utiliser le commutateur “/Node:“.
Vous pouvez donc renseigner un ou plusieurs noms de machine,(ou adresses IP) séparés par des virgules où même utiliser un fichier externe qu’il faudra simplement préfixer par “@” dans la commande.
Pour l’illustrer, je change un peu le scénario, en considérant que je veux connaître l’état du service d’impression sur mes différents serveurs.Je vais donc créer mon fichier contenant les noms de mes serveurs (1 par ligne). Bon il est vrai que pour 300 serveurs, on utilisera une moulinette pour collecter ces informations dans un annuaire, ou via un outil, voire un script spécifique (pourquoi pas en WMI ;-))

type c:\machines.txt
ARAGORN
LEGOLAS
GIMLI
FRODON

wmic /node:@C:\machines.txt /output:%temp%\spools.htm service where “displayname like ‘%impression%'” get displayname, name, state /format:htable

Et voila le resultat !

Bon, je reconnais qu’au final la commande est un peu longue, mais ça vaut bien la peine, non ?

Ultime précision :
Lorsque vous exécutez la commande, votre compte de session ne dispose surement pas des privilèges suffisants pour l’interrogation à distance des machines (comment ça vous être connecté en tant qu’administrateur du domaine ?!…) . Utilisez donc le commutateur “/USER:Domain\admin” juste avant le verbe puis entrez le mot de passe lorsque vous y êtes invité.

Conclusion
Vous l’aurez surement compris, WMI et sa console offre un potentiel d’administration considérable sous réserve de prendre le temps de découvrir chaque objet et sa richesse (Et je n’ai pas parlé des capacités de gestion événementielle pour la surveillance dynamique; passionnant mais un sujet à part entière). J’espère que cette lecture vous sera profitable et qu’un jour WMI n’aura plus de secret, pour votre plus grand confort en tant qu’administrateur Windows …
Et pour ceux que ça intéresse, je vous invite à poursuivre l’aventure du scripting sous WSH et PowerShell.

Postscriptum :
N’oubliez pas que WMI utilise RPC et que la présence d’un pare-feu Windows risque de bloquer l’accès. Pour ouvrir le pare-feu sur Windows XP SP2, tapez la commande suivante ;

netsh firewall set service remoteadmin enable
Ok.

Depuis Windows 2003-R2, Microsoft propose un service Web “WS-Management” pour faire des appels “WMI over HTTP/S”. Ce service web, se configure via la commande “WinRM” et depuis peu, vous pouvez télécharger ce composant “WS-Management v1.1” pour Windows XP et 2003.
Malheureusement, la console WMI n’est pas capable de l’exploiter et à moins que Microsoft décide d’adapter WMIC en conséquence (ce qui est très peu probable), il faudra passer à PowerShell. Mais rassurez-vous, vos efforts et investissements sur WMI ne seront pas vains puisque PowerShell est en mesure de dialoguer nativement avec les objets WMI, avant de vous aventurer dans les objets du Framework .NET…

 

Bonne continuation

Christophe Mandin

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. Apprenez comment les données de vos commentaires sont utilisées.