Windows management instrumentation

Méthodes d'accès

Nous avons vu précédemment un exemple de script permettant d'afficher la date de dernier démarrage de la machine, voici le code :

Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem",,48)
For Each objItem in colItems
WScript.Echo "LastBootUpTime: "& objItem.LastBootUpTime
Next

WMI offre plusieurs méthodes permettant de référencer une instance ou un groupe d'instance (ou de classes). Il est possible d'utiliser object path ou encore WQL. Voici une description de ces deux méthodes.

Objects path

Le principe d'object path est de désigner en une simple chaîne de caractère l'objet voulu. WinMgmt permet deux syntaxes, l'une où l'on donne le chemin de l'objet séparé par des \ et par : pour la classe finale, l'autre où l'on donne directement le nom de la classe.
Dans les deux cas, on pourra spécifier une liste de propriétés avec leur valeurs afin de désigner l'objet recherché. Certaines propriétés sont des clefs primaires permettant d'identifier une instance sans ambiguïté. Le code suivant permet d'afficher l'adresse MAC d'un contrôleur réseau dont le DevideID est 19 (propriété clef) :

Set objSWbemObject = GetObject("winmgmts:\\.\root\CIMV2:Win32_NetworkAdapter.DeviceID='19'")

WScript.Echo "adresse Mac: "& objSWbemObject.MACAddress


Pour spécifier une instance de la classe Win32_Environment dont la propriété Name vaut TEMP et la propriété UserName vaut HOST\\Josao, on pourra utiliser cette chaîne :

Win32_Environment.Name="TEMP",UserName="HOST\\Josao"

Dans le cas d'un singleton qui ne possède pas de propriétés étant des clefs primaires, le chemin est la concaténation du nom de la classe et de la chaîne =@

Par exemple, pour référencer un singleton SingletonTest créé au sommet de l'arborescence :

\\HOST\root\cimv2:SingletonTest=@

Il est a noter que les noms de classes sont insensibles à la casse. On ne pourra pas avoir :
       \\HOST\root\cimv2:Toto
et également la classe :
        \\HOST\root\cimv2:toto
par contre son référencement sera sensible à la casse ...



WQL


Il arrive souvent qu'on ne connaisse pas les propriétés d'un élément recherché, et que l'on souhaite récupérer toute les instances (parfois répondant à un certain critère) afin de sélectionner ensuite celle que l'on recherchait à l'origine. Ou il arrive également, tout simplement, que l'on veuille effectuer un traitement sur plusieurs objets du même type. Pour cela, Microsoft à inventer le WQL. Son fonctionnement est simple et sa syntaxe se rapproche du SQL. C'est la méthode utilisé dans le script au début de cette page. Commentons ce code :

'on se connecte au gestionnaire de la base CIM de l'ordinateur local
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")

'on soumet une requête au gestionnaire (winmgmts) définissant l'ensemble recherché
Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem",,48)

'puis on itère sur chaque élément afin d'effectuer le traitement
For Each objItem in colItems
WScript.Echo "LastBootUpTime: "& objItem.LastBootUpTime
Next

Dans l'exemple précédent il n'y avait qu'un seul élément dans la collection, mais on aurait pu travailler avec une vrai collection, comme par exemple la liste des services :

Select * FROM Win32_Service

On peut également exprimer des conditions et des jointures (bonne pratique SQL) :

Select * FROM Win32_Service WHERE State='Stopped'

On peut aussi sélectionner les propriétées à récupérer sur les instances :

Select Name, FreeSpace FROM Win32_LogicalDisk WHERE DeviceID='c:'

Il sera également possible d'exécuter des méthodes sur ces objets. Celles-ci étant définies pour chaque classe grâce au fichier MOF. On regrettera cependant le manque de méthode définie dans l'arborescence CIM, la majorité d'entre elles étant proposées par le constructeurs dans les classes finales.

Attention : Il faut se souvenir que certaines instances sont récupérées plus ou moins laborieusement. Le pire exemple étant de vouloir récupérer un fichier précis à partir de son nom et de sa représentation dans la base CIM ainsi :

#CIM_DataFile n'est pas abstraite
Select * FROM CIM_DataFile WHERE Name='pouet.tgz'

Le résultat sera l'écroulement total du disque dur puisque la base CIM ne contient pas les fichiers et que ces instances sont récupérées via une recherche classique, qui en plus de les lister, crée les objets pour comparer ensuite les propriétés.


Accès distant

Pour l'instant nous avons vu comment interagir avec la base WMI locale. Mais un des points forts de cette API est de permettre un accès distant aisé. Il suffit en fait de spécifier l'hôte dans la chaîne de connexion au gestionnaire WMI. Ce processus est à l'écoute des appels distants, traitera la requête et transmettra la réponse sur le réseau. Auparavant nous utilisions cette chaine de connexion :

"winmgmts:\\.\root\cimv2"

Le point désigne en fait l'ordinateur local, il suffit de remplacer ce point par une chaîne permettant l'identification d'un hôte.

"winmgmts:\\192.168.0.15\root\cimv2" ou "winmgmts:\\intranet\root\cimv2"

Voici un exemple de script (format vbscript) permettant de désinstaller "MSN Messenger" sur un machine dont l'adresse est demandée à l'utilisateur :

'on demande une saisie pour récupérer le nom de la machine, ou ip
host = InputBox("Entrer l'adresse de la machine distante ")

'on insere la chaine entre le nom du gestionnaire WMI et la base du schéma visé
if host <> "" then Set objWMIService = GetObject("winmgmts:\\"& host &"\root\cimv2")

'on récupère la liste des produits installés
Set colItems = objWMIService.ExecQuery("Select * from Win32_Product",,48)

'on itere sur chacun d'eux
For Each objItem in colItems
'si le nom contient la chaine "MSN Messenger", on le desinstalle
if instr(objItem.Caption, "MSN Messenger") > 0 then objItem.Uninstall()
Next
End if

Pour cela il faudra simplement veiller à avoir le droit de se connecter à cette base, soit grâce à des droits d'administrateurs sur la machine (de domaine ou locale) soit en ayant modifié les contrôles d'accès à cette base comme spécifié précédemment.

Grâce à cette technique on pourra effectuer le traitement sur toute les machines de l'entreprise facilement, en veillant bien sûr à avoir fait un peu de com. avant (BigBrother n'est pas loin).