Windows PowerShellTravailler sans script

Don Jones

Quand je parle de Windows PowerShell, lors d'une conférence, sur le groupe de discussion public de Windows PowerShell, voire sur mon site, je rencontre toujours des administrateurs qui me disent qu'ils « vont remettre à plus tard » leur apprentissage de Windows PowerShell. Pourquoi ? En général, la réponse est

« je n'ai pas le temps d'apprendre à créer des scripts pour l'instant ».

C'est un sentiment courant. Nous autres administrateurs avons autre chose à faire, et n'avons vraiment pas beaucoup de temps libre pour apprendre une nouvelle technologie. Cependant nous devons progresser, apprendre de nouveaux logiciels, tels que Windows Vista®, Windows Server® 2008 et Exchange Server 2007 de façon à continuer de maîtriser les technologies essentielles pour nos tâches. Windows PowerShell™ représente une grosse partie de ces technologies.

Une autre excuse qui revient souvent pour remettre au lendemain l'apprentissage de l'écriture de script dans Windows PowerShell est la « peur de se transformer en programmeur », comme un collègue administrateur l'a élégamment dit. Voici un domaine où je pourrais vous être utile. Vous serez surpris d'apprendre que vous pouvez faire des choses stupéfiantes avec Windows PowerShell, sans écrire une seule ligne de code.

Présentation du pipeline

J'ai déjà écrit sur le pipeline orienté objet, extrêmement souple et puissant, de Windows PowerShell. (L'expression « orienté objet » peut laisser entendre que je passe du côté des programmeurs, mais je m'inscris en faux). L'une des choses que je préfère avec le pipeline est qu'il peut être utilisé de façon interactive. Vous pouvez obtenir des résultats instantanés et raffiner ces résultats de façon à obtenir exactement ce que vous voulez. Par exemple, supposons que je doive souhaite obtenir un inventaire de l'espace disque disponible sur plusieurs ordinateurs distants. Admettons que les noms de ces ordinateurs figurent dans un fichier texte appelé C:\Computers.txt. C'est juste un fichier de texte brut avec un nom d'ordinateur sur chaque ligne, on est encore loin de la base de données.

Pour commencer, je vais essayer d'obtenir ces informations à partir de mon ordinateur local. Après tout, si j'y arrive sur un ordinateur, la même tâche sur plusieurs ordinateurs devrait être très facile. Et, promis, pas question d'écrire un script ! Je vais tout faire de façon interactive dans l'environnement de ligne de commande et obtenir des résultats dès que j'appuierai sur la touche Entrée.

Quelques petites informations techniques. Lorsque vous devez faire l'inventaire des informations de gestion sur des ordinateurs distants, il est recommandé d'utiliser Windows® Management Instrumentation (WMI). Maintenant, supposons que, dans le cadre de cet exemple, je ne sache plus rien sauf qu'il faut utiliser WMI. Je passe donc sur Live Search et tape « Windows wmi espace disque disponible » comme terme de recherche. Plusieurs résultats remontent avec l'expression « Win32_LogicalDisk » dans l'extrait. Il me semble que c'est une classe WMI, peur-être même celle que je recherche. Je ne vais pas me fatiguer à cliquer sur les autres résultats. Par contre, j'entre « Win32_LogicalDisk » comme nouveau terme de recherche et l'un des premiers résultats renvoie sur une page de documentation Win32_LogicalDisk du site MSDN® (msdn2.microsoft.com/aa394173.aspx). Donc j'ouvre la page et vois que l'une des propriétés de cette classe est FreeSpace, ce qui semble très prometteur.

Recherche d'une applet de commande

Pour l'étape suivante, je dois rechercher une applet de commande qui récupérera les propriétés d'une classe WMI. L'un des aspects les plus remarquables de Windows PowerShell est qu'il dispose de fonctionnalités intuitives extraordinaires, en clair son environnement de ligne de commande se laisse découvrir facilement. Donc je tape Help *WMI* pour découvrir ce que l'environnement de ligne de commande sait du fonctionnement avec WMI. Les résultats, illustrés à la figure 1, sont l'alias Gwmi et son applet de commande cible, Get-WMIObject. En fait, vous disposez de deux accès à la même fonctionnalité, ce qui signifie que je n'ai pas à me torturer les méninges pour savoir laquelle utiliser. Les deux font la même chose et Gwmi est plus court à taper, je vais donc l'utiliser :

Figure 1 Ce que l'environnement de ligne de commande sait sur WMI

Figure 1** Ce que l'environnement de ligne de commande sait sur WMI **(Cliquer sur l'image pour l'agrandir)

PS C:\> gwmi win32_logicaldisk

Windows PowerShell n'est pas sensible à la casse, il sait que nous autres administrateurs n'avons pas le temps de nous arrêter sur des détails secondaires, tels que l'utilisation de la touche majuscule.

Les résultats de cette commande, illustrés à la figure 2, incluent mes cinq lecteurs locaux et leurs propriétés FreeSpace, qui semblent exprimées en octets. Je trouve également une propriété DriveType pour chacun de ces lecteurs et je vois des valeurs de 2, 3 et 5 sur mon ordinateur.

Figure 2 Tous mes lecteurs locaux et leurs propriétés FreeSpace

Figure 2** Tous mes lecteurs locaux et leurs propriétés FreeSpace **(Cliquer sur l'image pour l'agrandir)

Applet de commande du mois

Vous auriez pu utiliser Get-Content pour lire le contenu d'un fichier texte. Il traite chaque ligne du fichier comme un objet [de chaîne], transmettant ces objets aux autres applets de commande via le pipeline. Mais Get-Content dispose d'un certain nombre d'options qui le rendent plus souple : Le paramètre -readCount, par exemple, permet de spécifier le nombre d'objets [de chaîne] transférés à la fois dans le pipeline (la valeur par défaut consiste à tout envoyer), tandis que le paramètre –totalCount contrôle le nombre total de lignes lues dans le fichier. Deux de ces paramètres sont utiles pour manipuler de très gros fichiers qu'il peut être intéressant de traiter par sections pour des raisons de performances.

Voici une autre option qui vous facilitera la vie. Le paramètre -encoding permet de lire correctement un large éventail de types de codage de fichiers, notamment Unicode, ASCII, UTF7, UTF8 et bien d'autres. Pour consulter la liste complète des types de codage pris en charge, exécutez help gc (gc est un alias pour Get-Content).

Tri des données

À ce stade, j'ai deux problèmes. Tout d'abord, toutes ces propriétés m'ennuient, je cherche FreeSpace. Ensuite, je ne veux pas savoir quel est l'espace libre sur les lecteurs optiques, les lecteurs amovibles ou les unités réseau. Seuls les disques durs locaux m'intéressent. Cette propriété DriveType pourra sans doute m'aider à faire la distinction. Je reviens à mon navigateur Web et constate que la documentation contient un tableau expliquant les différentes valeurs de DriveType. Je recherche DriveType 3, qui indique que le lecteur est un disque dur local. Je décide de voir si la commande Gwmi peut filtrer mes données. L'exécution de Help Gwmi –full indique de façon détaillée comment la commande fonctionne et donne quelques exemples. Je vois un paramètre qui paraît utile, –filter, et décide de l'essayer :

gwmi win32_logicaldisk -filter "drivetype = 3"

Ça marche ! Ma liste de lecteurs contient uniquement les disques fixes locaux. Mon deuxième problème est résolu. Je vais pouvoir revenir sur le premier et me débarrasser de toutes les propriétés dont je ne veux pas.

J'exécute Get-Command pour obtenir la liste de toutes les applets de commande de Windows PowerShell et je finis par trouver Select-Object. La description dit que cette applet « sélectionnera les propriétés spécifiées d'un objet ou d'une série d'objets ». Donc j'essaye ceci :

gwmi win32_logicaldisk -filter "drivetype = 3" | select freespace

En canalisant les résultats de Gwmi vers Select (l'alias de Select-Object) j'obtiens précisément la propriété voulue. Oups. Ces résultats ne sont pas si bons que ça, car j'ai juste une liste de numéros, je ne sais pas à quels lecteurs correspondent ces chiffres et les valeurs d'espace libre. Donc je reviens à la documentation et vois que la propriété DeviceID contient la lettre de lecteur. Je retape rapidement ma commande et essaie à nouveau :

gwmi win32_logicaldisk -filter "drivetype = 3" | select deviceid,freespace

Parfait ! Et puisque seules deux propriétés sont dans la liste, l'environnement de ligne de commande est capable de placer les informations dans un joli tableau. (Le mois prochain j'expliquerai comment Windows PowerShell choisit d'utiliser des listes ou des tableaux).

Calcul

J'ai récupéré des informations sur l'espace libre, mais c'est en octets et ce n'est pas vraiment aussi utile que les méga-octets ou les giga-octets. Il est clair que la propriété FreeSpace ne suffit pas à elle seule, il me faut plutôt une valeur calculée à partir de cette propriété. L'applet de commande ForEach-Object (ou l'un de ses nombreux alias, tels que %) peut m'aider. Cette applet de commande me permet d'utiliser une variable spéciale, $_, pour référencer le disque logique actif et d'accéder séparément aux propriétés des disques et de faire un ou deux calculs. Voici ma commande modifiée :

gwmi win32_logicaldisk -filter "drivetype = 3" | % { $_.deviceid; $_.freespace/1GB }

Tout ce que j'ai fait ici a été de supprimer Select et de le remplacer par l'alias de ForEach-Object (%). Cette applet de commande veut simplement savoir ce qu'elle doit faire avec chaque Win32_LogicalDisk rencontré et je lui ai dit d'obtenir la propriété DeviceID et de diviser la propriété FreeSpace par un gigaoctet. Windows PowerShell « sait » ce qu'est un Ko, un Mo et un Go, par conséquent mon résultat sera en gigaoctet.

De nombreux ordinateurs

Maintenant que ceci fonctionne pour un ordinateur, il est temps de l'appliquer à plusieurs systèmes. Je sais comment obtenir le contenu d'un fichier texte. Pour cela il suffit de procéder comme au bon vieux temps de MS-DOS®, avec la commande Type, qui dans Windows PowerShell se trouve être un alias de Get-Content.

Type c:\computers.txt

Je veux passer sur tous ces ordinateurs et exécuter la commande WMI que j'ai déjà utilisée. L'applet de commande ForEach Object porte bien son nom. C'est donc le moment de tout révéler, comme dans les émissions de décoration à la télé, et de regarder ma commande finale :

type c:\computers.txt | % { $_; 
gwmi –computername $_ win32_logicaldisk -filter "drivetype=3" | % { $_.deviceid; $_.freespace/1GB} }

Effrayant, n'est-ce pas ? Du fait de mon usage exclusif des alias au lieu des noms d'applet de commande, c'est dur à lire. Cependant, c'est assez facile à déchiffrer si vous prenez les différents éléments un par un :

  • Je commence par « typer » le contenu de mon fichier texte.
  • Je canalise son contenu vers ForEach-Object.
  • ForEach-object renvoie l'élément actuel, avec la variable $_. (Le nom de l'ordinateur actif.)
  • ForEach-Object exécute ensuite ma commande WMI, qui contient un autre appel de ForEach-Object.

Le développement de ces noms d'alias en noms d'applet de commande facilite les choses. Voici donc la même commande, mais cette fois-ci j'ai explicité les applets de commande et réparti la commande sur plusieurs lignes pour examiner chaque section plus facilement :

Get-Content C:\Computers.txt | 
ForEach-Object { 
 $_; Get-WMIObject –computername $_ 
Win32_LogicalDisk -filter "DriveType=3" | 
 ForEach-Object { 
 $_.DeviceID; $_.FreeSpace/1GB
 }
}

Les résultats, pas très esthétiques mais fonctionnels, sont illustrés à la figure 3.

Figure 3 Les résultats définitifs

Figure 3** Les résultats définitifs **(Cliquer sur l'image pour l'agrandir)

Pas de script

Le but de cette procédure détaillée est de démontrer que vous pouvez utiliser Windows PowerShell sans aucun script. Et, avec juste quelques exemples comme celui-ci, assortis d'un peu d'exploration dans Windows PowerShell même, vous pourrez trouver tous les éléments nécessaires pour accomplir les tâches que vous vous êtes fixées.

Windows PowerShell est ici pour durer. Pourquoi ne pas commencer à apprendre comment l'utiliser dès maintenant ? Vous finirez par vous demander comment vous avez pu vous en passer et le spectre d'un script ne vous empêchera plus de vous y plonger.

Don Jones est le gourou principal des scripts chez SAPIEN Technologies et formateur pour Scriptingtraining Com. Vous pouvez le joindre par le biais de son site Web à l’adresse suivante : ScriptingAnswers.com.

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