Windows management instrumentation

Architecture

Principe de fonctionnement

Supposons que l'on désire récupérer la date de démarrage d'une machine, pour cela on pourra exécuter le script suivant (son étude sera réalisée plus tard) :

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

Voici un schéma retraçant les interactions entre les différents éléments composant WMI :

principe de fonctionnement

1 - Notre script, l'application de gestion, tente d’accéder à un objet pour le gérer. Ici on veut récupérer l'instance de la classe Win32_OperatingSystem, représentant le système d'exploitation actuellement chargé sur la machine, puis déterminer sa date de démarrage.

2 - Le gestionnaire WMI détermine si l'information est stocké dans le conteneur WMI ou si elle est fourni par un provider.

3 - Si c'est à un provider de fournir l'information, WMI le charge et lui transmet la requête.

3bis - Dans notre cas l’instance est trouvé dans le conteneur WMI et est retourné à l’application de gestion qui l'affiche.

Ici WinMgmt est un service représentant le CIM Object Manager (connu sous le nom de CIMON).

Base CIM

Le Conteneur WMI du schéma précédent est une base CIM. Cette base est une arborescence de classe représentant des familles d'éléments logiques ou physiques. Chaque noeud est une classe héritant des propriétés et des méthodes de ses parents.

base cim


Ainsi on obtient des classes hiérarchisées dont les spécificités vont croissantes avec la profondeur dans l'arbre. La base CIM décrit au maximum les classes communes pour définir une machine standard. Chaque feuille de l'arbre reste cependant une classe abstraite que le constructeur devra définir pour coller au maximum au système courant.

Voici une branche de l'arborescence obtenue sur un ordinateur hébergeant Microsoft Windows. Les classes dont le nom commence par CIM_ font parti de l'arborescence normée dans WBEM, celle commençant par Win32_ sont l'implémentation finale du constructeur :

exemple schema cim

Microsoft a créé la classe Win32_Printer implémentant des méthodes communes à toute imprimante et ajoutant certaines plus spécifiques à Windows.

Il est possible d'utiliser la notion de polymorphisme lors du développement des applications d'administration. Ainsi, un tel logiciel qui utiliserait WBEM et ne faisant référence qu'à des objets de type CIM_Printer pourra être utilisé sur n'importe autre quel système implémentant WBEM. Cependant le prix à payer pour cette portabilité sera l'impossibilité d'utiliser des méthodes propres aux sous-classes (Win32_Printer ou Solaris_Printer) sans faire de l'introspection.


Il est à noter également qu'une classe n'a pas besoin d'être une feuille pour en hériter, il est même possible d'étendre de la classe de base.

Structure de classe

Représentation logique

Les classes de la base CIM possèdent des propriétés par défaut facilitant le travail du développeur.

__Class nom de la classe.
__Derivation liste reprenant la hiérarchie de la classe ou instance courante.
__Dynasty nom de la classe au sommet de la hiérarchie d’héritage.
__Genus valeur permettant la distinction entre classe et instance (1 classe, 2 instance)
__Namespace espaces de noms liés à la classe courante.
__Path chemin complet de l’objet, serveur et namespace compris.
__Property_Count nombre de propriétés non système de cette classe.
__Relpath chemin relatif.
__Server nom du serveur fournissant cette classe ou instance.
__Superclass nom de la super-classe directe.

Représentation physique

Ces classes sont représentées par des fichiers MOF. Sur le même principe qu'un fichier IDL, ils permettent à tout logiciel de connaître le comportement d'un objet appelé à distance. Ces fichiers sont utilisés lorsqu'un développeur veut enregistrer sa définition de classe dans la base CIM.

Voici un exemple du code à fournir pour une classe représentant un utilisateur (le fichier mof originel contenait plusieurs classes) :

//*************************************************************************
// 2000 Kevin Hughes and David Wohlferd
// File: MSJSampProvClasses.mof
//*************************************************************************

//*************************************************************************
//* Class: MSJ_User
//* Derived from: MSJ_Account
//*************************************************************************
[Description("The MSJ_User class represents user accounts belonging to a "
"given domain"): ToSubClass,
dynamic: ToInstance ToSubClass,
provider("MSJSampProv"): ToInstance ToSubClass,
UUID("{6E5A57A0-6944-44f0-8140-0D70C2021439}"): ToInstance]
class MSJ_User : MSJ_Account
{
[Description("The name of the user account"): ToSubClass]
string Name;

[Description("The domain on which the user account is "
"defined"): ToSubClass]
string Domain;

[Description("The security identifier associated with the "
"account"): ToSubClass,
read: ToSubClass]
string SID;

[Description("Specifies the logon script path for this user "
"account"): ToSubClass,
read: ToSubClass,
write: ToSubClass]
string LogonScriptPath;

[Implemented, Description("The Rename method allows one to change the "
"name of a user account"): ToInstance ToSubClass]
uint32 Rename([IN] string NewName);
};
...

On retrouve la liste des méthodes, chacun d'eux possédant des attributs. Le format est basé sur IDL. Voici une brève comparaison :

### méthode prenant une chaîne en entrée et retournant un entier

#format MOF
class MSJ_User : MSJ_Account {
uint32 Rename([IN] string NewName);
}

#format IDL
interface MSJ_User : MSJ_Account {
short rename(in string newWanme);
}

Microsoft permet d'ajouter une classe à la base CIM via la commande mofComp. On regrettera cependant l'absence de documentation chez Microsoft, qui sera difficilement trouvable dans le standard mof.
 

Espace de noms

Un des points importants à retenir lors de l'utilisation de WMI est le concept d'espace de nom. Chaque connexion au gestionnaire de base CIM se fait sur un espace de nom bien déterminé. Ensuite, si dans l'exécution du programme on cherche à accéder à une classe présente dans un autre espace de nom, il faudra effectuer une autre connexion. Chaque espace de nom possède son propre schéma. Voici une liste des espaces de nom que l'on trouve sur une machine Microsoft :
namespace1
On retrouve l'espace de nom par défaut qui sera CIMV2 (pour version 2) contenant l'arborescence de classes définit par WBEM ainsi que leurs l'implémentation Microsoft. On trouvera aussi des espaces de noms proposant des schémas relatifs à des rôles de la machine (serveur DNS, LDAP ...) mais cela ne fait plus partie de la norme WBEM et n'est présent que sur les machines Microsoft.

Le principe d'espace de nom permet de référencer des objets du même nom à différents endroits. De plus, on peut créer des espaces de noms que l'on inclura dans un autre. On obtient ainsi une hiérarchie d'espace de nom.

Ci dessous on peut constater que la base CIM contient une classe __NAMESPACE dont les instances sont celles listées ci-dessus.

namespace2


La seule limitation lors de l'héritage des classes, est que la classe dérivée doit être dans le même espace de nom que la super-classe. En fait, on s'efforcera de créer les classes supplémentaires dans son propre espace de nom si celle-ci n'hérite d'aucune.

Sécurité

Etant donné que WMI permet également de gérer des machines distantes, il est possible de définir un contrôle d'accès à ces ressources. Pour cela aller dans l'outil de Gestion de l'ordinateur et sélectionner propriétés de l'élément Services et application > Contrôle WMI puis l'onglet sécurité :

 controle d acces

On peut ainsi gérer les droits d'accès, d'écriture, d'exécution, ou d'appel distant d'une base selon des comptes locaux ou de domaine. Il n'est malheureusement pas possible d'affecter ces droits à certains points de l'arborescence.

Pour cela, une gestion de la sécurité plus poussée à été récemment proposé par Microsoft, voici un (lien) décrivant le procédé.