Hé, vous le scripteur !Pas besoin de travailler dur pour être récompensé

Les scripteurs Microsoft

Télécharger le code de cet article: HeyScriptingGuy2008_06.exe (150KB)

Pendant des siècles, les gens ont pensé que le travail assidu était une récompense en soi, que la véritable satisfaction venait d'une journée de travail honnête...bref, vous voyez où je veux en venir. Travaillez dur et sans vous plaindre (pensez à Cendrillon), et, un jour, vous serez récompensé.

Remarque : Mais est-ce vraiment possible ? Si vous travaillez dur, non seulement vous serez plus heureux mais, un jour, vous serez récompensé pour vos efforts ? Pourquoi nous posez-vous une telle question ?

Bien sûr, Cendrillon a eu de la chance. Après tout, si vous habitez avec une belle-mère et quelques demi-sœurs malveillantes, vous avez toutes les chances de travailler dur. Mais qu'en est-il si vous n'est pas si chanceux ? Que se passe-t-il si vous ne vivez pas avec une belle-mère et quelques demi-sœurs malveillantes ? Comment êtes-vous supposé passer des journées de travail ingrates, exténuantes et interminables ? Vous pensez que vous allez vraiment trouver le bonheur ?

Eh bien, si vous souhaitez vraiment travailler comme un dingue, les scripteurs suggèrent que vous essayiez d'écrire un script qui affiche des données sous la forme d'un tableau net et agréable, comme les résultats affichés à la figure 1.

Figure 1 Résultats sous forme de tableau

Figure 1** Résultats sous forme de tableau **(Cliquez sur l'image pour l'agrandir)

Comme nous l'avons dit, Cendrillon a eu beaucoup de chance : Elle nettoyait la maison du sol au plafond, et une fois ce travail terminé, s'asseyait parmi les cendres et la suie. Mais même Cendrillon aurait hésité avant d'écrire un script qui puisse afficher des données sous la forme d'un tableau. S'asseoir parmi les cendres et la suie, c'est une chose. Écrire un script qui affiche des données sous la forme d'un tableau est entièrement différent.

Remarque : À moins de devoir vous asseoir dans la cheminée pour écrire vos scripts ; il s'agit alors, à peu de chose près, de la même chose.

Pourquoi Cendrillon hésiterait-elle devant cette tâche ? Parce que c'est trop difficile. Le seul moyen d'afficher des données sous la forme d'un tableau dans VBScript consiste à faire ce qui suit :

  • Commencez par déterminer la taille maximale de chaque colonne. Par exemple, vous pouvez souhaiter que le nom d'affichage d'un service contienne 52 espaces de caractère.
  • Calculez ensuite le nombre d'espaces dans un élément de données. Par exemple, le nom d'affichage Adobe LM Service contient 16 caractères.
  • Si le nom d'affichage dépasse la limite de 52 caractères, déterminez le nombre d'espaces à supprimer à la fin de la chaîne pour que le nom entre dans l'espace attribué. Si le nom d'affichage ne dépasse pas 52 espaces de caractère, déterminez combien d'espaces vides doivent être ajoutés à la fin de la chaîne pour que la longueur soit exactement de 52 caractères.
  • Répétez cette procédure pour la série suivante de données. Et la suivante. Et ainsi de suite.

Si vous connaissez l'histoire de Cendrillon, alors vous savez qu'il est possible que votre bonne fée apparaisse de manière non annoncée, transforme une souris en un administrateur système (aucun commentaire sur la facilité d'exécution de cette tâche !), puis la souris écrira ce script à votre place. Mais ne comptez pas trop sur ce dénouement. Vous êtes probablement seul ici.

Cependant, si on regarde la vie du bon côté, vous serez la personne la plus satisfaite au monde. Parce que vous serez également la personne ayant travaillé le plus durement au monde. La personne ayant travaillé le plus durement, et de loin.

Bien sûr, certaines personnes souhaitent échanger une petite satisfaction contre la possibilité de ne pas avoir à travailler si dur. Si vous êtes une de ces personnes, vous pensez probablement, « Dieu merci, les scripteurs sont là. Ils vont me dire comment modifier une souris en un administrateur système, puis me dire comment obliger cette souris à formater mes résultats dans un tableau. » J'ai bien peur que nous ayons des mauvaises nouvelles pour vous : les scripteurs n'ont aucune idée sur la manière de transformer une souris en un administrateur système. (Bien que nous puissions transformer un administrateur système en une souris, si cela vous est utile.) Nous ne savons pas comment vous pouvez obtenir que quelqu'un d'autre écrive des scripts à votre place, des scripts qui afficheront des données sous la forme d'un tableau.

Mais peu importe. Tant que vous exécutez Windows® XP ou Windows Server® 2003 (ce qui est le cas pour beaucoup d'entre vous), vous n'avez pas besoin d'une souris pour écrire vos scripts à votre place. (Non, désolé, j'ai bien peur que ça ne fonctionne pas sur Windows Vista®.) À la place et avec un effort minimal, vous pouvez effectuer ceci grâce à l'objet Microsoft.CmdLib. Regardez le script d'exemple à la figure 2.

Figure 2 Création d'un affichage sous forme de tableau

Dim arrResultsArray()
i = 0

Set objCmdLib = _
  CreateObject("Microsoft.CmdLib")
Set objCmdLib.ScriptingHost = _
  WScript.Application

arrHeader = Array("Display Name", _
  "State", "Start Mode")
arrMaxLength = Array(52, 12, 12)
strFormat = "Table"
blnPrintHeader = True
arrBlnHide = Array(False, False, False)

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" _
  & strComputer & "\root\cimv2")

Set colServices = objWMIService.ExecQuery _
  ("Select * FROM Win32_Service")

For Each objService In colServices
  ReDim Preserve arrResultsArray(i)
  arrResultsArray(i) = _
  Array(objService.DisplayName, _
    objService.State,objService.StartMode)
  i = i + 1
Next
objCmdLib.ShowResults arrHeader, _
  arrResultsArray, arrMaxLength, _
  strFormat, blnPrintHeader, arrBlnHide

Au cas où vous vous poseriez la question, Microsoft.CmdLib est un objet COM expédié avec Windows XP et Windows Server 2003. Cet objet a plusieurs fonctionnalités différentes. Pour plus d'informations, tapez cmdlib.wsc /? à l'invite de commande et lisez les commentaires dans le fichier de script qui apparaît à l'écran. Aujourd'hui, nous nous intéressons uniquement à une seule fonctionnalité de Microsoft.CmdLib : la capacité d'afficher des données sous la forme d'un tableau.

Ceci mène à une question évidente : Comment afficher des données sous la forme d'un tableau ? Voyons si nous pouvons faire quelque chose. Comme vous pouvez le voir, notre script d'exemple commence par la définition d'un tableau dynamique appelé arrResultsArray :

Dim arrResultsArray()

Dans un script typique, les données sont renvoyées sur l'écran aussi rapidement qu'elles sont extraites. Mais pourquoi espériez-vous que les scripteurs fassent tout d'une manière typique ? Dans ce script, nous n'allons pas renvoyer les données comme elles ont été extraites. À la place, nous allons stocker toutes les données renvoyées dans un tableau, puis laisser Microsoft.CmdLib effectuer le formatage et l'affichage des données pour nous.

En d'autres termes, voilà pourquoi nous commençons par créer un tableau dynamique (c'est-à-dire un tableau qui peut être redimensionné tout au long du script). Après avoir défini le tableau, nous définissons la valeur d'une variable counter appelée i sur 0. Nous allons utiliser cette variable pour suivre la taille actuelle du tableau.

Au cas où vous vous poseriez la question, nous définissons la valeur i sur 0 parce que le premier élément dans un tableau reçoit toujours le numéro de référence 0. Par conséquent, lorsque nous ajoutons le premier élément dans le tableau, nous ajoutons l'élément 0 au lieu de l'élément 1.

Nous devons ensuite lancer notre instance de l'objet Microsoft.CmdLib. Voilà ce que représentent les deux lignes de code suivantes :

Set objCmdLib = _
CreateObject("Microsoft.CmdLib")
Set objCmdLib.ScriptingHost = WScript.Application

Et cela nous amène à ce petit bloc de code :

arrHeader = Array("Display Name", "State", "Start Mode")
arrMaxLength = Array(52, 12, 12)
strFormat = "Table"
blnPrintHeader = True
arrBlnHide = Array(False, False, False)

Ce que nous faisons ici, c'est définir quelques paramètres pour configurer nos résultats. Sur la première ligne, nous attribuons des valeurs à un tableau appelé arrHeader. Comme vous pouvez vous y attendre, elles correspondent à des en-têtes pour chaque colonne dans notre tableau de résultats. Pour ce script d'exemple, nous récupérons les informations sur les services s'exécutant sur un ordinateur, puis affichons les valeurs des propriétés DisplayName, State et StartMode pour chaque service.

Il n'est pas surprenant que nous attribuions à notre tableau les noms de colonne DisplayName, State et StartMode (bien que nous aurions pu facilement attribué à nos colonnes les noms A, B C, Pierre, Marie et Carine ou tout autre chose. Il n'est pas nécessaire que les noms de colonne soient identiques aux noms de propriétés).

Remarque : Il existe de nombreuses variations de l'histoire de Cendrillon, y compris les noms de ses demi-sœurs. Dans la version Disney de Cendrillon, les demi-sœurs s'appellent Javotte et Anastasie. Il se trouve que ces deux noms sont les premiers et deuxièmes prénoms de nos scripteurs !

Dans la deuxième ligne de code, nous attribuons les valeurs à un autre tableau, appelé arrMaxLength. Ce tableau contient la taille de chaque colonne dans le tableau. Dans nos résultats, nous souhaitons allouer 52 espaces de caractère à la colonne 1 (le nom d'affichage du service). Nous voulons ensuite allouer 12 espaces à l'état de service et 12 espaces au mode de démarrage. (Microsoft.CmdLib insère automatiquement un espace vide entre les colonnes.) Si nous souhaitons que les tailles de nos colonnes soient 52, 12 et 12 espaces de caractère (ce que nous faisons), nous utilisons le code qui ressemble à ce qui suit :

arrMaxLength = Array(52, 12, 12)

La troisième ligne spécifie le format des résultats de nos données. Nous souhaitons que les données s'affichent sous forme de tableau. Par conséquent, nous définissons la valeur strFormat (la variable qui contient le type de résultats) sur Table. Supposez plutôt que nous souhaitions afficher les données en tant que liste de valeurs séparées par des virgules. Dans ce cas, nous définirions le format sur CSV, comme suit :

strFormat = "CSV"

Et nous obtiendrions donc des résultats semblables à ce que nous avons ici :

"Display Name","State","Start Mode"
"Adobe LM Service","Stopped","Manual"
"Adobe Active File Monitor V4","Stopped","Manual"
"Alerter","Stopped","Manual"
"Application Layer Gateway Service","Running","Manual"
"Apple Mobile Device","Running","Auto"
"Application Management","Stopped","Manual"

Remarquez comment Microsoft.CmdLib a non seulement placé des virgules entre chaque article, mais a également inséré les valeurs individuelles entre guillemets. Il s'agit d'une fonctionnalité plus agréable que vous pourriez le penser. Après tout, pour faire ceci manuellement, vous devez utiliser le code suivant :

Wscript.Echo Chr(34) & objService.DisplayName & Chr(34) & "," & Chr(34) & objService.State & Chr(34) & "," & Chr(34) & objService.StartMode & Chr(34)

Mouais.

Qu'est-ce que c'est ? Vous n'aimez pas les tableaux et vous n'aimez pas le format CSV non plus ? Dans ce cas, essayez de définir le format sur List, ce qui vous offre des résultats semblables à ce qui suit :

Display Name: Adobe LM Service
State:        Stopped
Start Mode:   Manual
Display Name: Adobe Active File Monitor V4
State:        Stopped
Start Mode:   Manual

Mais nous nous éloignons... (ce que nous sommes enclins à faire de temps à autre !) Après avoir défini le format des résultats, nous définissons la valeur d'une variable appelée blnPrintHeader sur True :

blnPrintHeader = True

Nous utilisons blnPrintHeader pour demander à Microsoft.CmdLib d'imprimer les en-têtes de colonnes. Que se passe-t-il si nous ne souhaitons pas imprimer les en-têtes de colonnes ? Pas de problème. Dans ce cas, définissez blnPrintHeader sur False :

blnPrintHeader = False

Enfin, nous obtenons la ligne de code suivante :

arrBlnHide = Array(False, False, False)

Lorsqu'il est temps d'afficher vos données, Microsoft.CmdLib vous offre la possibilité d'afficher ou de masquer une colonne. Pour masquer une colonne (c'est-à-dire, supprimer les données pour une propriété particulière), définissez la valeur de cette propriété sur True. Pour afficher une colonne, définissez la valeur sur False.

Dans nos résultats, nous affichons les valeurs pour les propriétés DisplayName, State et StartMode, dans cet ordre. Nous utilisons donc les valeurs False, False, False dans notre tableau. Que se passerait-il si nous souhaitions afficher DisplayName, masquer State et afficher StartMode ? Dans ce cas, nous utiliserions la ligne de code suivante :

arrBlnHide = Array(False, True, False)

N'oubliez pas d'utiliser False pour afficher une colonne et True pour masquer une colonne.

À ce stade, nous sommes prêts à afficher certaines données ou nous le serions si nous disposions de quelques données. (Les scripteurs ont-ils un jour écrit un script qui n'a pas affiché de données, puis passé un temps incroyable à déboguer ce script, pour découvrir qu'ils avaient tout simplement oublié de récupérer des données ? Euh, bien sûr que non ! Qu'est-ce qui vous faire dire cela ?)

En gardant ceci à l'esprit, l'étape suivante consiste à effectuer la liaison avec le service Windows Management Instrumentation (WMI) sur l'ordinateur local, utilisez alors la méthode ExecQuery pour récupérer les informations sur tous les services installés sur cet ordinateur :

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colServices = objWMIService.ExecQuery ("Select * FROM Win32_Service")

Il est nécessaire de noter que vous n'êtes pas obligé de travailler uniquement avec des données WMI ici. Comme vous pouvez vous y attendre, Microsoft.CmdLib peut fonctionner avec tout type de données. WMI est simplement une manière pratique de récupérer beaucoup de données.

Une fois que nous disposons de notre collection de données associées aux services, nous définissons une boucle For Each pour effectuer un cycle via tous les services dans la collection. Cependant, au lieu de renvoyer les valeurs de propriété pour chaque service, nous exécutons le code suivant :

ReDim Preserve arrResultsArray(i)
arrResultsArray(i) = Array(objService.DisplayName, objService.State,objService.StartMode)
i = i + 1

Que faire dans ce bloc de code ? À la ligne 1, nous redimensionnons notre tableau, avec la commande ReDim Preserve pour non seulement redimensionner le tableau mais également conserver toutes les données existantes de ce tableau. (sans le mot-clé Preserve, le tableau sera redimensionné, mais aucune donnée actuellement dans ce tableau ne serait effacée.)

Quelle taille du tableau souhaitons-nous ? La première fois par la boucle, nous créons un tableau de taille 0. En d'autres termes, nous créons un tableau contenant un élément. Et comment savons-nous à coup sûr que nous créons un tableau de taille 0 ? Parce que nous utilisons la variable counter i et que cette variable est égale à 0.

Par conséquent, si nous utilisons la variable i pour représenter la taille du tableau, est-ce que cela ne revient pas à définir la taille sur 0 ? Si mais à chaque fois que nous nous traversons la boucle, nous incrémentons la valeur de i de 1. Comme vous pouvez le constater, c'est ce que nous faisons à la ligne 3 de notre bloc de code.

Cela nous laisse avec une seule ligne de code :

arrResultsArray(i) = Array(objService.DisplayName, objService.State,objService.StartMode)

Il nous suffit de prendre les valeurs de propriété qui nous intéresse (DisplayName, State et StartMode) et de les ajouter au tableau arrResultsArray. Remarquez que nous n'ajoutons pas les valeurs de propriété de manière individuelle. À la place, nous les ajoutons comme un tableau de valeurs. Je vous l'accorde, c'est un peu insolite : ceci signifie que chaque élément dans le tableau arrResultsArray sera un autre tableau. Voilà comme Microsoft.CmdLib fonctionne.

Bien sûr, cela peut vous inquiéter. « Un tableau de tableaux ? Comment puis-je accéder à toutes les valeurs individuelles dans un tableau plein de tableaux ? » Ne vous affolez pas. C'est facile : Laissez Microsoft.CmdLib s'en occuper pour vous.

Remarque : Désolé, mais accéder à toutes les valeurs individuelles dans un tableau de tableaux, c'est à peu près la seule chose que Microsoft.CmdLib peut faire pour vous. Cependant, nettoyer les chambres de votre belle-mère malveillante, faire la vaisselle et repriser des vêtements de vos demi-sœurs diaboliques sont envisagés pour la version suivante de l'objet.

En fait, nous pouvons afficher nos données (sous la forme d'un tableau net) en appelant simplement la méthode ShowResults et transmettant la méthode de tous les tableaux et toutes les variables que nous avons configurées précédemment dans le script :

objCmdLib.ShowResults arrHeader, arrResultsArray, arrMaxLength, strFormat, blnPrintHeader, arrBlnHide

À quoi tout cela va-t-il ressembler ? Cela ressemblera aux résultats formatés que nous espérions obtenir lorsque nous regardions la figure 1.

Pas mal, non ? Vous obtenez des résultats agréables et vous avez à peine travaillé. (et votre script suivant sera encore plus facile, parce que tout ce que vous aurez à faire, ce sont quelques changements mineurs à ce premier script.)

Maintenant, il est vrai que vous n'obtiendrez pas la même satisfaction que Cendrillon qui était une esclave jour et nuit pour pouvoir afficher les résultats de script dans un tableau. Et, pour être honnête, vous n'épouserez probablement pas un prince non plus ! Mais, bon, ça, ça ne faisait pas partie du contrat ! Mais c'est un petit prix à payer pour obtenir des résultats agréables d'un script VBScript, surtout lorsque vous prenez en considération ce que sont les princes d'aujourd'hui.

Et qui sait : vous pourriez peut-être épouser quand même un prince. Après tout, même la royauté a besoin d'obtenir des informations sur tous les services installés sur leurs ordinateurs, n'est-ce pas ?

Les scripts embrouillés du Dr. Scripto

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

Juin 2008 : Chemin PowerShell

Dans chacun de ces jeux, reliez les lettres horizontalement, verticalement et en diagonale pour créer le nom d'une cmdlet Windows PowerShell. Chaque lettre ne peut être utilisée qu'une seule fois. Voici un exemple :

La cmdlet créée dans ce jeu est New-Alias. À votre tour. Voici trois jeux supplémentaires :

ANSWER:

Les scripts embrouillés du Dr. Scripto

Réponses : Chemin PowerShell, juin 2008

Read-Host

Set-AuthenticodeSignature

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 and CMP Media, LLC. Tous droits réservés. Toute reproduction, totale ou partielle, est interdite sans autorisation préalable..