WMI, PHP et plein d’autres trucs en trois ou quatre lettres (part 3)

Déjà la troisième partie, et toujours pas la moindre ligne de PHP jusqu’à présent…

De la théorie à la pratique 

Réjouissez-vous, car le purgatoire est bientôt fini, vous allez pouvoir dégainer votre PHPEdit, votre Notepad++, bref votre IDE préféré et taper quelques lignes de PHP. Comme certains d’entre vous n’en ont peut-être jamais écrit, on va faire très simple : un script PHP est un simple fichier texte, au même titre qu’une page HTML, mais dans lequel nous allons demander au pré-processeur PHP d’exécuter des commandes.

Pour éviter qu’il se mélange les pinceaux (et surtout que vous n’obteniez des résultats étonnants), il faut lui indiquer où se trouve le code PHP. Ceci se fait tout simplement grâce à deux balises. Elles sont indispensables, immuables, obligatoires, et en rouge ci-dessous :

1
2
3
<?php
// Le code PHP sera ici
?>

Il suffit d’enregistrer le fichier avec l’extension .php dans le répertoire spécifié dans la configuration d’Apache, puis d’appeler le script depuis votre navigateur préféré, en général en accédant à l’adresse https://127.0.0.1/toto.php (oui, vous pouvez appeler votre script toto.php, ce n’est pas interdit).

Note : par défaut, le répertoire où stocker vos fichiers .php est <répertoire où Apache est installé>htdocs. Si vous utilisez EasyPHP, c’est un peu plus tordu car cela dépend de la version installée… Il suffit cependant de faire un clic droit sur l’icône d’EasyPHP dans le Systray, de choisir Administration, puis dans la page qui s’ouvre, regarder la section Web local : vous verrez alors le répertoire racine de votre serveur Web, par exemple C:UsersDédéDocumentsEasyPHP-DevServer-14.1VC9datalocalweb. C’est dans ce répertoire (ou dans un sous-répertoire) que vous devrez mettre votre fichier .php. Lorsque vous appellerez l’adresse https://127.0.0.1/, Apache lira le contenu du répertoire localweb sur le disque.

Il existe tout un tas de tutoriels du plus ou moins bonne qualité sur PHP. Si vous en trouvez un bourré de fautes, fuyez-le comme la peste. Il aura souvent été écrit par un ado boutonneux l’ayant largement pompé sur le site d’un camarade, en conservant les mêmes erreurs.

Allez on y va

Après ce petit rappel (ou cette découverte fabuleuse, au choix), nous allons enfin écrire un vrai script PHP, qui lancera une requête WMI et affichera les valeurs obtenues. Magnifique, non ? Allez, créez une nouveau fichier texte, et faites un copier-coller de ceci (j’ai retiré les numéros de ligne pour que ce soit plus pratique pour vous) :

<?php

if(!extension_loaded("com_dotnet"))
{
echo "Il faut l'extension php_com_net.dll dans le php.ini !";
exit;
}

?>

C’est tout ? Oui. mais on va décortiquer un petit peu tout ça. Ici, on indique à PHP : « Si l’extension com_dotnet – autrement dit php_com_dotnet.dll – n’est PAS chargée (le ! devant extension_loaded est une négation), alors affiche (echo) le message, puis arrête d’exécuter le script (exit). » Vous aurez noté que certaines lignes – pas toutes – se terminent par un point-virgule. En gros, les lignes qui ne définissent pas une structure (des conditions if, des boucles for ou while…) doivent avoir ce point-virgule final, sous peine de générer une erreur. Faites le test et retirant celui de la ligne qui commence par echo, et vous verrez. Pour les débutants, c’est une habitude à prendre.

Lors de l’exécution de ce script, si vous avez bien chargé l’extension com_dotnet, il ne se passera rien. Ecran vide. Que d’chi. Nada. Et c’est normal, puisqu’on n’a pas indiqué quoi faire à PHP. Donc il ne fait rien. Le script s’arrête, Apache envoie la page (vide !) au navigateur et c’est tout. Est-ce que l’exit est obligatoire ? Non, techniquement le script se serait terminé juste après l’echo. Mais comme on va ajouter des instructions ensuite (si l’extension est bien chargée), cet exit évitera d’exécuter le reste du script après avoir affiché le message, ce qui provoquerait forcément des erreurs.

Les choses sérieuses commencent

Comme je vous l’ai dit dans les parties précédentes, WMI permet d’interroger le PC local (celui sur lequel vous exécutez PHP) ou un PC distant (pour peu qu’il soit démarré, accessible via le réseau et que le service WMI soit démarré). N’espérez pas pouvoir interroger un PC via internet, il y a de fortes chances que ça coince quelque part. Sur votre réseau local par contre, en théorie aucun problème (à moins d’avoir un firewall logiciel qui bloque. Si vous rencontrez un problème, parlez-en commentaire, on cherchera une solution).

Pour l’instant, nous nous contenterons d’interroger le PC local, nous verrons comment se connecter à distance ensuite. En local, nul besoin d’indiquer l’adresse IP, un simple point (.) suffit. Nous allons donc nous connecter au namespace root/cimv2 local via COM en PHP. Pour ça, ajoutez simplement la ligne suivante, juste avant la balise ?>  :

$WbemServices=new COM ("winmgmts:\\.\root\cimv2");

Voilà, c’est tout. On crée un nouvelle instance COM nommée $WebmServices qui va utiliser le protocole winmgtms pour se connecter au namespace \.rootcimv2. Les backslashes sont doublés car comme vous le savez peut-être, le backslash est un caractère d’échappement. Et lorsqu’on veut qu’il apparaisse depuis une chaîne, il faut le doubler.

(Amis puristes, oui je sais, il n’y a pas de récupération en cas d’exception, chaque chose en son temps. On va dire que $WebmServices est bien créé systématiquement).

Etape suivante, on va se servir de cette connexion pour exécuter une requête WQL (elle va vous rappeler des souvenirs), afficher les valeurs des propriétés Vendor et Version de la classe Win32_ComputerSystemProduct (comme précédemment, ajoutez ces lignes avant la balise ?>) :

$compsysprod = $WbemServices->ExecQuery("Select * from Win32_ComputerSystemProduct");

foreach($compsysprod as $csp)
{
$cspvendor=$csp->Vendor;
$cspversion=$csp->Version;

echo "Constructeur : ".$cspvendor."<br />";
echo "Modèle : ".$cspversion."<br />";
}

Enregistrez le fichier, retournez sur votre navigateur, et si tout va bien, vous devriez obtenir quelque chose de ce genre :

Si vous voyez autre chose que LENOVO et ThinkPad T440, c’est bien aussi, hein

Félicitations, vous venez pour la première fois d’interroger votre PC en utilisant WMI ! Revenons un peu plus en détails sur le code :

$compsysprod = $WbemServices->ExecQuery("Select * from Win32_ComputerSystemProduct");

Ici, nous appelons la méthode ExecQuery (qui permet d’exécuter la requête fournie en paramètre) de l’instance $WbemServices, et allons stocker tout ça dans la variable $compsysprod (un objet de type variant. Pour ceux qui seraient tentés par faire un var_dump dessus, sachez que ça ne vous appendra hélas pas grand chose).

Ensuite, nous faisons une boucle foreach parmi LES résultats (ici il n’y en a qu’un, mais il peut y en avoir plusieurs) enfin plus exactement chaque itération (que nous appelons $csp) de $compsysprod :

foreach($compsysprod as $csp)
 

Puis, nous récupérons les valeurs des propriétés Vendor et Version de chaque itération (objet) $csp, puis nous les affichons (echo):

{
$cspvendor=$csp->Vendor;
$cspversion=$csp->Version;

echo "Constructeur : ".$cspvendor."<br />";
echo "Modèle : ".$cspversion."<br />";
}

 

Vous voyez, rien de bien compliqué comme je me tue à vous le dire ! Variez un peu les plaisirs en sélectionnant parmi les classes Win32_quelquechose les propriétés qui vous intéressent, et affichez-les. Utilisez wbemtest comme indiqué dans la deuxième partie de cette série d’articles pour cela.

Comme parfois le nom d’une propriété peut porter à confusion, une petite astuce toute simple pour trouver des informations : ouvrez un nouvel onglet, allez sur Google, et tapez le nom de la classe qui vous intéresse. Allez sur le lien (en général le premier) qui arrive et qui ressemble à celui-ci :

Win32_ComputerSystemProduct class (Windows) – MSDN

Vous arrivez directement sur la page du MSDN, où sont listées et expliquées les différentes propriétés de la classe. Des heures de lecture en perspective…

Une fois n’est pas coutume, je vous remets le code source complet de notre exercice du jour. N’hésitez pas à jouer avec, à améliorer le résultat (par exemple, faites un joli tableau HTML), etc. Nous nous arrêterons ici pour cette partie, la prochaine vous montrera comment interroger un PC distant, car au niveau du code, cela change un peu.

<?php

if(!extension_loaded("com_dotnet"))
{
echo "Il faut l'extension php_com_net.dll dans le php.ini !";
exit;
}

$WbemServices=new COM ("winmgmts:\\.\root\cimv2");
$compsysprod = $WbemServices->ExecQuery("Select * from Win32_ComputerSystemProduct");

foreach($compsysprod as $csp)
{
$cspvendor=$csp->Vendor;
$cspversion=$csp->Version;

echo "Constructeur : ".$cspvendor."<br />";
echo "Modèle : ".$cspversion."<br />";
}
?>

A bientôt !

Laisser un commentaire

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

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