Hé, vous le scripteur !Les Jeux sont ouverts ! Oh, et aussi un peu de XML

Les scripteurs Microsoft

Télécharger le code de cet article: HeyScriptingGuy2008_02.exe (151KB)

Vous savez, dès qu'on parle des légendes du monde sportif, les mêmes noms reviennent inévitablement : Michael Jordan. Pelé. Muhammad Ali. Eddy Merckx ScooterK et MrRat. Johnny...

Ouais, c'est ça, vous... Non, vous êtes sérieux ? Vous ne connaissez vraiment pas ScooterK et MrRat ? Bon, pour ceux qui ne se tiennent manifestement pas au courant sur les Jeux de script d'hiver (du 15 février au 3 mars au Centre de scripts TechNet, rendez-vous sur microsoft.com/technet/scriptcenter/funzone/games), ScooterK et MrRat sont de vraies légendes, des concurrents qui ont réalisé des scores parfaits dans au moins une division des Jeux de script d'hiver 2007.

Et voici la partie vraiment sympa : pensez-vous vraiment avoir une chance de devenir une légende du football comme Pelé ? Probablement pas. Pouvez-vous espérer devenir le champion du monde des poids lourds ? Bon, certains des Scripteurs répondent bien au critère « poids lourds », mais la partie « champion de boxe » ne colle pas vraiment. Mais vous (oui, vous !) pouvez facilement devenir le prochain ScooterK ou MrRat.

Remarque : En théorie, vous pourriez tout aussi bien devenir le prochain Michael Jordan. Tout ce qu'il vous suffit de faire, c'est de grandir pour mesurer 1,98 m, gagner 6 titres de champion NBA et remporter deux fois les autres Jeux (olympiques).

Ne vous cassez pas la tête ; nous allons vous dire comment devenir le prochain ScooterK ou MrRat (et peut-être même le prochain Bizzy ou H2Data). Il vous suffit pour cela de vous présenter au Centre de scripts et de participer aux Jeux de script. Le 15 février, nous mettrons en ligne 10 épreuves différentes (10 défis de script), et vous mettrons au défi d'en réussir au moins un. Écrivez un script qui résout le problème que nous posons, et envoyez-le aux Scripteurs. (Vous trouverez des instructions détaillées sur la page d'accueil des Jeux de script). Nous testerons votre script et, s'il marche, nous vous attribuerons des points. Réussissez les 10 épreuves et vous deviendrez vous aussi une légende du monde sportif. Ou du moins du monde sportif de script, ce qui est à peu près la même chose.

Les Jeux de script (15 février - 3 mars) sont amusants et stimulants. Et le mieux, c'est que les Jeux de script sont ouverts à tout le monde. Vous êtes relativement nouveau dans l'écriture de scripts d'administration système ? Alors inscrivez-vous dans la catégorie Débutant ; nous organisons des compétitions séparées pour les débutants en VBScript, Windows PowerShellTM et (nouveau cette année) Perl. Vous trouvez la catégorie Débutant un peu trop facile ? Alors essayez-vous à la catégorie Avancé, qui proposé également des compétitions en VBScript, Windows PowerShell et Perl.

Les Jeux (on vous a dit qu'ils se déroulaient du 15 février au 3 mars ?) sont tout simplement l'événement de la saison dans l'écriture de scripts, et vous ne voulez pas les manquer. Rendez-vous dès maintenant sur la page d'accueil du Centre de scripts pour des astuces et conseils sur l'entraînement pour la compétition, puis revenez le 15 février, quand nous déclarerons les Jeux officiellement ouverts.

Du 15 février au 3 mars. Au cas où vous n'auriez pas compris.

Pardon ? En fait, nous sommes tout à fait d'accord avec vous : la publication d'une nouvelle chronique Hé, vous le Scripteur ! et l'annonce des Jeux de script, c'est probablement trop d'excitation pour un seul mois. Mais pour que les bonnes gens de TechNet Magazine soient heureux (notre principal objectif dans la vie, cela va sans dire), nous avons décidé de prendre le risque et de quand même publier une nouvelle chronique.

Il y a exactement un an (incroyable, ça fait déjà un an ?), nous avons publié une chronique expliquant comment utiliser un script pour lire un fichier XML. En revanche, cette chronique n'expliquait pas comment utiliser un script pour créer, écrire et modifier un fichier XML. Ce mois-ci, nous sommes ici pour corriger cela. Vous aimeriez savoir comment écrire un script capable de créer un fichier XML ? Il suffisait de le demander. Euh, demander puis attendre un an pour que nous nous y mettions. La figure 1 reproduit ce script. Cela peut certes sembler compliqué, mais nous expliquerons comment tout cela fonctionne.

Figure 1 Créer un fichier XML

Set xmlDoc = _
  CreateObject("Microsoft.XMLDOM")  
  
Set objRoot = _
  xmlDoc.createElement("ITChecklist")  
xmlDoc.appendChild objRoot  

Set objRecord = _
  xmlDoc.createElement("ComputerAudit") 
objRoot.appendChild objRecord 
  
Set objName = _
  xmlDoc.createElement("ComputerName")  
objName.Text = "atl-ws-001"
objRecord.appendChild objName  

Set objDate = _
  xmlDoc.createElement("AuditDate")  
objDate.Text = Date  
objRecord.appendChild objDate  

Set objIntro = _
  xmlDoc.createProcessingInstruction _
  ("xml","version='1.0'")  
xmlDoc.insertBefore _
  objIntro,xmlDoc.childNodes(0)  

xmlDoc.Save "C:\Scripts\Audits.xml"  

Pour commencer, nous créons une instance de l'objet Microsoft.XMLDOM. Comme vous l'avez peut-être deviné, c'est l'objet qui nous permet de travailler avec des fichiers XML. Notre objectif est de produire un fichier XML simple qui ressemble à la figure 2.

Figure 2 Notre cible : un fichier XML simple

Figure 2** Notre cible : un fichier XML simple **

Pour créer ce fichier XML, la première chose que nous devons faire est créer le nœud racine (ITChecklist). Comment procédons-nous ? Comme ceci :

Set objRoot = _
  xmlDoc.createElement("ITChecklist")  
xmlDoc.appendChild objRoot  

C'était plutôt facile, non ? Il nous a suffit d'invoquer la méthode createElement, en transmettant à createElement le nom que nous voulons donner au nœud racine. Nous appelons ensuite simplement la méthode appendChild, en transmettant la référence objet à notre nouvel élément (objRoot) comme unique paramètre de méthode. À ce stade, nous avons un nœud racine.

Mais attendez, ce n'est pas fini. Ensuite, nous créons le nœud ComputerAudit, un nœud enfant du nœud ITChecklist qui représente l'information pour un ordinateur seul. Comme vous pouvez le voir, le code permettant de créer ce nœud est similaire au code utilisé pour créer le nœud racine :

Set objRecord = _
  xmlDoc.createElement("ComputerAudit") 
objRoot.appendChild objRecord 

La seule différence est la suivante : lorsque nous avons créé le nœud racine, nous avons invoqué appendChild sur notre document XML lui-même. (Notez la référence objet xmlDoc). Pour ajouter un nouveau nœud enfant à la racine, nous invoquons appendChild sur le nœud racine (objRoot) au lieu du document XML. C'est aussi facile que ça.

Il est tout aussi simple d'ajouter des nœuds ComputerName et AuditDate comme nœuds enfants de ComputerAudit. Pour ce faire, nous suivons un processus similaire : nous invoquerons createElement pour créer un nouveau nœud, et nous invoquerons appendChild pour ajouter ce nouveau nœud au fichier.

(Question rapide : Á partir d'où invoquons-nous appendChild cette fois-ci ? C'est ça : à partir d'objRecord, le nœud parent (ComputerAudit) que nous venons de créer).

Au fait, comme les nœuds ComputerName et AuditDate doivent contenir des valeurs, il est important que nous indiquions également une valeur pour la propriété « Text » de chacun de ces nœuds juste avant de les ajouter au document.

Tout cela devrait devenir clair une fois que nous aurons regardé le code qui crée réellement le nœud ComputerName :

Set objName = _
  xmlDoc.createElement("ComputerName")  
objName.Text = "atl-ws-001"
objRecord.appendChild objName  

Comme on pourrait s'y attendre, le code permettant de créer AuditDate est presque identique. Il nous faut simplement indiquer un nom de nœud différent en invoquant createElement et en attribuant une valeur différente à la propriété « Text ».

Pfff... On vous simplifie vraiment trop la tâche, vous ne trouvez pas ?

Une fois que nous avons terminé de créer les nœuds pour notre premier enregistrement (qui est dans ce cas le seul), nous exécutons ce joli petit bloc de code :

Set objIntro = _
 xmlDoc.createProcessingInstruction _
  ("xml","version='1.0'")  
xmlDoc.insertBefore _
  objIntro,xmlDoc.childNodes(0)  

Celui-ci insère simplement la balise <?xml version="1.0" ?> au début du fichier, garantissant ainsi que nous avons un document XML bien formé.

À ce stade, tout ce qu'il nous reste à faire, c'est invoquer la méthode « Save » et enregistrer notre nouveau fichier sous C:\Scripts\Audits.xml :

xmlDoc.Save "C:\Scripts\Audits.xml"  

Et comme cela, nous avons un tout nouveau document XML.

En fait, c'est assez utile : vous savez maintenant comment créer un fichier XML à l'aide d'un script. Bien sûr, la plupart du temps, vous n'aurez pas réellement besoin de créer un nouveau fichier XML, mais plutôt d'ajouter de nouvelles données à un fichier existant. Alors, les Scripteurs vont-ils montrer à tout le monde comment faire cela ?

Vous savez, au départ, nous avions décidé que nous n'allions pas le faire. Mais ensuite, comme nous sommes gentils et généreux, nous avons décidé de proposer un deal aux lecteurs de TechNet Magazine : si tous les lecteurs de ce magazine acceptent de participer aux Jeux de script 2008, en retour, nous vous montrerons comme utiliser un script pour ajouter des données à un fichier XML. Alors, tout le monde est d'accord pour participer aux Jeux de script ?

Bon... on vous attend. Oui, vous, le gars qui habite dans son bled paumé.

Voilà, on préfère ça. Et croyez-nous, nous allons bien nous amuser pendant les Jeux de script, tout le monde s'y éclate à chaque fois. Nous vous le promettons.

Bon, comme nous pensons que vous êtes des gens de parole, nous allons vous montrer un script qui peut ajouter des données à un fichier XML existant. Examinez la figure 3.

Figure 3 Ajouter à un fichier XML

Set xmlDoc = _
  CreateObject("Microsoft.XMLDOM")

xmlDoc.Async = "False"
xmlDoc.Load("C:\Scripts\Audits.xml")

Set objRoot = xmlDoc.documentElement
  
Set objRecord = _
  xmlDoc.createElement("ComputerAudit")
objRoot.appendChild objRecord

Set objFieldValue = _
  xmlDoc.createElement("ComputerName")
objFieldValue.Text = "atl-ws-100"
objRecord.appendChild objFieldValue

Set objFieldValue = _
  xmlDoc.createElement("AuditDate")
objFieldValue.Text = Date
objRecord.appendChild objFieldValue
  
xmlDoc.Save "C:\Scripts\Audits.xml"  

Comme vous pouvez le voir, ce n'est pas affreusement différent du script qui a créé le fichier XML. Nous commençons par créer une instance de l'objet Microsoft.XMLDOM, puis nous définissons la propriété Async sur False, ce qui indique au script que nous voulons charger le document de façon synchrone plutôt qu'asynchrone. Quelle différence cela fait-il ? Et bien, si nous chargions le document de façon asynchrone, le script serait libre de continuer bien que le document ne soit pas entièrement chargé. Inutile de dire que le fait d'essayer d'exécuter une tâche sur un document qui n'existe pas encore pourrait rapidement créer des problèmes. En nous assurant que notre fichier XML se charge de manière synchrone, nous nous garantissons également que le fichier sera entièrement chargé avant le démarrage de notre script.

En parlant de chargé, l'haleine de notre... euh, laissez tomber, on va oublier ça. Nous allons plutôt invoquer la méthode Load pour ouvrir le fichier C:\Scripts\Audits.xml. Dès que le fichier est ouvert, nous utilisons cette ligne de code pour créer une instance de la classe documentElement, ce qui nous lie à la racine du document. Dans ce cas, il s'agit bien sûr du nœud ITChecklist :

Set objRoot = xmlDoc.documentElement

Nous avons fait le plus dur. Nous créons une nouvelle instance du nœud ComputerAudit, en utilisant la méthode appendChild pour ajouter ce nouveau nœud au fichier. Nous créons ensuite de nouvelles instances des nœuds ComputerName et AuditDate, en indiquant les valeurs appropriées (respectivement atl-ws-100 et la date actuelle) pour chaque nouveau nœud. Nous rangeons ces deux éléments dans le nouveau nœud ComputerAudit que nous venons de créer, invoquons la méthode Save pour enregistrer le fichier, puis nous pouvons retourner dans la joie à nos scripts pour les prochains Jeux de script.

Lesquels, au cas où nous aurions oublié de le préciser, sont prévus du 15 février au 3 mars au Centre de scripts TechNet.

Jusque-là, tout va bien. Nous pouvons créer un nouveau fichier XML, et nous pouvons ajouter de nouveaux enregistrements à ce fichier. C'est bien beau tout ça, mais il nous reste du pain sur la planche : par exemple, comment modifier des enregistrements existants dans le fichier ? Et bien, voici au moins une façon de procéder, illustrée à la figure 4.

Figure 4 Modifier le XML

Set xmlDoc = _
  CreateObject("Microsoft.XMLDOM")

xmlDoc.Async = "False"
xmlDoc.Load("C:\Scripts\Audits.xml")

Set colNodes=xmlDoc.selectNodes _
  ("/ITChecklist/ComputerAudit " & _
   "[ComputerName = 'atl-ws-100']/AuditDate")

For Each objNode in colNodes
   objNode.Text = Date
Next
  
xmlDoc.Save "C:\Scripts\Audits.xml"  

La partie importante de ce script survient lorsque nous invoquons la méthode selectNodes, qui détermine les enregistrements renvoyés par notre requête. Comme vous pouvez le voir, lorsque nous avons invoqué selectNodes, nous avons pris le soin d'indiquer deux critères : nous voulons uniquement les enregistrements dont l'attribut ComputerName est égal à atl-ws-100, et nous voulons uniquement récupérer l'attribut AuditDate.

Remarque : vous ne voyez pas comment cela fonctionne ? Alors jetez un œil à notre premier article sur la manipulation des fichiers XML (www.microsoft.com/technet/technetmag/issues/2007/02/HeyScriptingGuy/default.aspx?loc=fr/) ; la syntaxe de requête selectNodes y est expliquée plus en détail.

Comme à son habitude, selectNodes renvoie une collection de tous les enregistrements XML qui répondent aux critères indiqués. Cela veut également dire que vous pouvez facilement mettre à jour la valeur de l'attribut AuditDate (le seul attribut que nous avons demandé) en créant une boucle For Each qui parcourra tous les éléments de cette collection, puis, au sein de cette boucle, attribuera une nouvelle valeur à AuditDate :

For Each objNode in colNodes
   objNode.Text = Date
Next

Qu'y a-t-il ? Vous vous demandez si nous pourrions modifier plusieurs attributs à la fois ? Oui, nous pourrions. Mais malheureusement, pas aujourd'hui : nous devrons aborder ça dans une chronique future.

Vous dites que vous avez une autre question : Comment mettre à jour la date d'audit pour tous les ordinateurs dans le fichier ? C'est facile : il vous suffit d'utiliser le script de la figure 5.

Figure 5 Modifier la date d'audit

Set xmlDoc = _
  CreateObject("Microsoft.XMLDOM")

xmlDoc.Async = "False"
xmlDoc.Load("C:\Scripts\Audits.xml")

Set colNodes=xmlDoc.selectNodes _
  ("/ITChecklist/ComputerAudit/AuditDate")

For Each objNode in colNodes
   objNode.Text = Date
Next
  
xmlDoc.Save "C:\Scripts\Audits.xml"

La différence entre ce script et notre script précédent de modification de XML ? Avec celui-ci, nous n'avons pas indiqué que nous voulions uniquement afficher les enregistrements pour lesquels l'attribut ComputerName était égal à atl-ws-100. En laissant ce critère de côté, nous récupérons par défaut tous les enregistrements.

Jetons un œil à un dernier script avant de nous quitter. Supposons que notre vieux pote atl-ws-100 a joué sa dernière partie de solitaire avant de rejoindre le grand cimetière informatique dans le ciel.

Remarque théologique : où vont les ordinateurs quand ils meurent ? Il se trouve qu'ils sont généralement donnés à l'un des Scripteurs. Par exemple, on a donné un ordinateur portable au Scripteur qui écrit cette chronique parce que, « Vous faites beaucoup de choses utiles pour Microsoft, et vous devriez vraiment avoir un ordinateur portable ». Le seul inconvénient à cette offrande généreuse ? L'ordinateur était cassé et ne pouvait même pas être allumé. Ce qui était probablement aussi bien. Il se trouve qu'il n'avait pas non plus de disque dur.

Pour boucler la grande boucle de la vie du silicium, nous devons supprimer atl-ws-100 de notre fichier XML. Comment allons-nous procéder ? Regardez la figure 6.

Figure 6 Supprimer du fichier XML

Set xmlDoc = _
  CreateObject("Microsoft.XMLDOM")

xmlDoc.Async = "False"
xmlDoc.Load("C:\Scripts\Audits.xml")

Set colNodes=xmlDoc.selectNodes _
  ("/ITChecklist/ComputerAudit " & _
   "[ComputerName = 'atl-ws-100']")

For Each objNode in colNodes
  xmlDoc.documentElement.removeChild _
    (objNode)
Next
  
xmlDoc.Save "C:\Scripts\Audits.xml"  

Comme vous pouvez le voir, ceci ressemble à notre script précédent, celui qui modifiait la propriété AuditDate. Il y a seulement deux différences, en fait. La première, c'est que nous ne nous sommes pas embêtés à indiquer une valeur de propriété dans notre requête selectNodes. En faisant ça, nous obtenons l'intégralité de l'enregistrement XML pour atl-ws-100 :

Set colNodes=xmlDoc.selectNodes _
  ("/ITChecklist/ComputerAudit " & _
   "[ComputerName = 'atl-ws-100']")

La seconde, c'est que dans notre boucle For Each, nous invoquons simplement la méthode removeChild pour supprimer tous les enregistrements où ComputerName est égal à atl-ws-100 :

xmlDoc.documentElement.removeChild _
  (objNode)

Et voilà. Adieu, atl-ws-100. Nous aurions aimé mieux te connaître.

Bon, certains rédacteurs de TechNet Magazine lisent-ils encore la chronique de ce mois ? Vous dites qu'ils sont tous partis essayer l'énigme de script mensuelle ? Excellent. Maintenant que plus personne ne lit par-dessus notre épaule, nous pouvons vous dire ceci : arrêtez ce que vous être en train de faire (comme lire ce magazine, par exemple), et rendez-vous au Centre de scripts pour vous préparer aux Jeux de script. Après tout, vous avez tout le temps pour lire TechNet Magazine. Mais les Jeux de script, ça n'arrive qu'une fois par an, et pendant une période limitée en plus (pour être plus précis, du 15 février au 3 mars). Ne les manquez pas !

Remarque : Maintenant que vous le dites, effectivement, nous avons attendu que vous ayez lu toute notre chronique avant de vous dire d'arrêter de lire TechNet Magazine ? On se demande bien pourquoi...

Les scripts embrouillés du Dr. Scripto

Le défi mensuel qui teste non seulement vos compétences de résolution d'énigme, mais également vos compétences d'écriture de script.

Février 2008 Symboles mystères

Le clavier informatique comporte un grand nombre de caractères aux allures étranges. Le plus étrange, c'est que la plupart de ces caractères ont en fait une utilisation spécifique dans les langages de script tels que VBScript ou Windows PowerShell. Voyons si vous pouvez faire correspondre chaque symbole à son utilisation de script. Nous avons fait le premier pour vous.

ANSWER:

Les scripts embrouillés du Dr. Scripto

Réponse : Symboles mystères, février 2008

  

Les scripteurs Microsoft travaillent pour (enfin, sont employés par) Microsoft. Lorsqu’ils ne sont pas en train de jouer au base-ball, d’entraîner une équipe ou de regarder un match (ou de se livrer à de multiples autres activités), ils dirigent le Script Center TechNet. Vous pouvez le vérifier vous-même sur www.scriptingguys.com.

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