Windows PowerShellDes commandes simples Une administration puissante

Don Jones

Cette rubrique est basée sur une version préliminaire de Windows PowerShell. Toutes les informations contenues dans cette rubrique peuvent être amenées à évoluer.

Cela a pris du temps, mais aujourd'hui nous y sommes : Windows PowerShell est quasiment prêt à démarrer. Cela signifie que c'est désormais aux administrateurs Windows d'entrer dans le mouvement. Windows PowerShell propose sans doute la solution la plus facile et la plus souple pour automatiser une multitude de tâches administratives et ainsi améliorer l'efficacité de votre travail.

Mais, ce qui est encore plus important, Microsoft crée les consoles administratives graphiques de produits tels que Exchange Server 2007 et System Center 2007, intégrées à Windows PowerShell™. Ainsi, vous pourrez effectuer presque n'importe quelle tâche administrative à partir de Windows PowerShell. Microsoft prévoit à terme de poursuivre l'intégration des fonctionnalités d'administration de davantage de produits. Windows PowerShell pourrait donc finalement devenir le premier outil d'administration universel pour pratiquement tous les produits Microsoft server. Pour vous aider à démarrer, je traiterai régulièrement de Windows PowerShell dans cette nouvelle rubrique. Veillez à télécharger une copie du logiciel.

Puissance et simplicité

Comme son nom l'indique, Windows PowerShell est un environnement semblable à l'invite de commande (Cmd.exe) utilisée depuis Windows NT® 3.1. Cmd.exe ne va pas disparaître, mais depuis l'arrivée de Windows PowerShell, il y a peu de raisons de continuer à utiliser Cmd.exe.

L'utilisation de Windows PowerShell n'est pas si éloignée de celle de Cmd.exe, mis à part que Windows PowerShell est plus puissant. Comme Cmd.exe, Windows PowerShell dispose d'un langage de script intégré, mais celui-ci offre beaucoup plus de souplesse que le langage de commande Cmd.exe d'origine. Plus souple, dans quelle mesure ? Grâce à Windows PowerShell, vous pouvez automatiser des tâches extrêmement complexes à l'aide d'un langage qui contient seulement une demi-douzaine de mots-clés intégrés.

Maintenant que j'ai mentionné le script, je pense qu'il me faut à présent aborder la question de la sécurité. Windows PowerShell profite des connaissances acquises en matière de sécurité par Microsoft depuis plus d'une décennie. Par défaut, Windows PowerShell n'exécutera aucun script ; il peut seulement être utilisé de manière interactive pour exécuter des commandes individuelles. Si vous activez le script, vous pouvez demander à Windows PowerShell d'exécuter uniquement des scripts signés numériquement. Tout ceci dans le but de garantir que Windows PowerShell ne sera pas le prochain VBScript, un langage formidable dont l'usage a souvent été détourné pour créer des scripts malveillants. VBScript ne va pas disparaître non plus, mais vous allez très probablement trouver que Windows PowerShell est plus facile à utiliser pour accomplir de nombreuses tâches différentes.

Windows PowerShell vous permet d'effectuer presque toutes les opérations que vous auriez pu réaliser avec Cmd.exe. Par exemple, vous pouvez exécuter ipconfig et vous obtiendrez le résultat habituel. Cependant, Windows PowerShell propose un tout nouvel ensemble de commandes qui ne sont pas constituées de fichiers exécutables externes. Ces cmdlets (prononcer « command-lètes ») sont directement intégrées à Windows PowerShell. (Pour accéder aux cmdlets les plus utiles qui vous initieront à l'utilisation de Windows PowerShell, reportez-vous à la barre latérale « Top 10 des Cmdlets à utiliser immédiatement ».)

Top 10 des Cmdlets à utiliser immédiatement

  • La commande Get-Command permet d'afficher la liste de toutes les cmdlets disponibles.
  • La commande Get-Help permet d'afficher des informations d'aide sur les cmdlets et les concepts.
  • La commande Get-WMIObject permet d'afficher des informations de gestion en utilisant WMI.
  • La commande Get-EventLog permet d'afficher les journaux d'événements Windows.
  • La commande Get-Process permet d'afficher un ou plusieurs processus actifs sous forme de liste.
  • La commande Get-Service permet d'afficher un service Windows.
  • La commande Get-Content lit les données des fichiers texte, traitant chaque ligne comme un objet enfant.
  • La commande Add-Content permet d'ajouter du contenu dans un fichier texte.
  • La commande Copy-Item permet de copier des fichiers, des dossiers et d'autres objets.
  • La commande Get-Acl permet d'afficher des listes de contrôles d'accès (ACL).

Pour obtenir la liste complète des cmdlets fournies avec Windows PowerShell, visitez la page windowssdk.msdn.microsoft.com/en-us/library/ms714408.aspx.

Les noms des cmdlets ayant tous le format standard verbe/nom, ils se retiennent facilement. Par exemple, si vous exécutez la cmdlet Get-Command, vous obtiendrez la liste de toutes les cmdlets disponibles. Get-WMIObject est sans doute la cmdlet la plus utile pour un administrateur. Imaginons que vous voulez savoir quel Service Pack est exécuté sur le Serveur2. Il vous suffit d'exécuter la cmdlet :

Get-WMIObject Win32_OperatingSystem –Property ServicePackMajorVersion
 –Computer Server2

Pour obtenir la même information avec VBScript, il vous faudrait écrire plusieurs lignes de code. D'autres cmdlets vous permettent de traiter, parmi tant d'autres, des services (Start-Service, Stop-Service, etc), des processus (Stop-Process et autres), des fichiers (Rename-Item, Copy-Item, Remove-Item, Move-Item, par exemple), etc. La plupart de ces cmdlets ont même des noms de raccourcis, qu'on appelle des alias. Pour exécuter la commande Get-WMIObject, il vous suffit de saisir « gwmi ». Exécutez Get-Alias pour obtenir la liste de ces noms de raccourcis.

Pourquoi l'approche orientée objet est décisive

Basé sur le Microsoft® .NET Framework, Windows PowerShell est entièrement orienté objet. D'habitude, seul un développeur de logiciel serait enthousiasmé par cette idée, mais dans ce cas, l'approche orientée objet permet aux administrateurs de gagner un temps considérable. En effet, ces derniers peuvent désormais traiter des objets étendus dans un environnement texte. Examinez cet exemple :

Get-Process | Sort-Object pm –desc | Select-Object –first 10

Il s'agit d'une ligne unique comportant trois cmdlets différentes, séparées par des canaux (sur lesquels nous reviendrons dans un instant). La première cmdlet récupère tous les processus en cours d'exécution, puis transfère ces objets vers la commande Sort-Object. Cette deuxième cmdlet trie par ordre décroisant les objets de processus en fonction de leur consommation de mémoire physique. L'ensemble d'objets de processus triés est ensuite transféré vers Select-Object, qui extraie et affiche les 10 premiers objets. Résultat ? Cette simple ligne affiche les 10 objets qui consomment le plus de mémoire physique sur la machine, comme l'illustre la figure 1. Ceci est extrêmement efficace pour obtenir un aperçu rapide lors d'un dépannage.

Figure 1 Utilisation d'une Cmdlet simple pour effectuer un dépannage

Figure 1** Utilisation d'une Cmdlet simple pour effectuer un dépannage **(Cliquer sur l'image pour l'agrandir)

L'utilisation de canaux (caractères en forme de ligne verticale généralement situés sur la touche de barre oblique inverse sur les claviers américains) constitue un élément essentiel dans l'étendue des capacités de Windows PowerShell. Utilisez ce caractère pour transférer les objets d'une cmdlet à l'autre, pour affiner les résultats, les formater, etc. Ce mécanisme fonctionne car chaque cmdlet retourne un ou plusieurs objets au lieu du texte pur et fournit aux cmdlets suivantes l'intégralité de l'objet en vue de son traitement.

L'utilisation d'objets dans Windows PowerShell est prépondérante, jusque dans ses variables. Par ailleurs, vous n'avez pas à déclarer les variables en amont ; vous pouvez commencer simplement à les utiliser en faisant précéder le nom d'une variable par le caractère dollar ($). Même si cela n'est pas obligatoire, vous pouvez également indiquer à Windows PowerShell le type de données que vous voulez insérer dans la variable. Windows PowerShell met en correspondance la variable et l'un des types extrêmement puissants de .NET Framework, ce qui vous permet d'obtenir de nombreuses fonctionnalités intégrées supplémentaires. Par exemple, supposez que vous voulez demander un nom d'ordinateur et récupérer la version de Service Pack de cet ordinateur, mais vous ne savez pas si la personne qui saisit le nom de l'ordinateur entrera deux barres obliques inverses (comme \\Serveur2). Comme vous savez que la cmdlet Get-WMIObject ne nécessite pas les barres obliques inverses, vous pouvez sauvegarder le nom de l'ordinateur dans une variable de chaîne et utiliser la méthode Replace pour remplacer les barres obliques inverses par des chaînes vides, comme suit :

[string]$c = Read-Host "Enter computer name"
$c = $c.Replace("\","")
    Get-WMIObject Win32_OperatingSystem
    –Property  ServicePackMajorVersion
    –Computer $c

La valeur du paramètre –Computer est fournie dans la variable $c. Cette variable a été initialement créée comme une chaîne. Ainsi, elle a sélectionné toute la fonctionnalité du type de chaîne .NET Framework, y compris la méthode Replace. Bien sûr, il vous faudra du temps pour découvrir toutes ces fonctionnalités, mais vous les dénicherez facilement dans les exemples. Windows PowerShell lui-même simplifie l'apprentissage. Par exemple, si vous saisissez $c = $c. (n'oubliez pas le point) et que vous appuyez sur la touche de tabulation, Windows PowerShell affiche Clone(), la première méthode du type chaîne. Si vous maintenez la touche de tabulation appuyée, Windows PowerShell passera en revue toutes les méthodes disponibles. Fondamentalement, lorsque vous procédez ainsi, Windows PowerShell vous démontre ce qu'il sait faire avec une chaîne !

À présent, voici une tâche plus ardue. lire une liste de noms d'ordinateurs depuis un fichier, avec un nom par ligne, et afficher le numéro de Service Pack de chaque ordinateur. Dans VBScript, l'exécution de cette tâche nécessiterait au mois une douzaine de lignes de code. Dans Cmd.exe, il vous faudrait utiliser un fichier batch compliqué. Dans Windows PowerShell, il suffit de saisir une seule ligne pour exécuter cette tâche :

Get-Content "c:\computers.txt" | foreach  
{ $_; gwmi Win32_OperatingSystem -prop 
ServicePackMajorVersion -comp $_ }

La cmdlet Get-Content lit le contenu du fichier C:\Ordinateurs.txt. Chaque ligne du fichier devient un objet en tant que tel. Ce groupe d'objets (c.-à-d. les noms d'ordinateur) est transféré à la commande Foreach qui constitue tout simplement un alias pour la cmdlet ForEach-Object. Les commandes comprises dans les accolades sont répétées une fois par objet transféré. Dans cet exemple, cela signifie qu'elles sont exécutées une fois pour chaque nom d'ordinateur. La variable spéciale $_ contiendra l'objet courant (c.-à-d., le nom d'ordinateur courant).

Les accolades contiennent effectivement deux commandes : La première affiche simplement le nom d'ordinateur courant en éditant le contenu de $_. La deuxième correspond à la désignation « gwmi » que vous connaissez bien maintenant. Une liste des versions de Service Pack s'affiche pour chaque ordinateur répertorié dans ce fichier. Tout ceci a été effectué à l'aide d'une ligne de commande relativement simple.

Notez que les noms de paramètre –Property et –Computer ont été abrégés. Windows PowerShell n'a besoin que du stricte nécessaire pour distinguer de façon univoque les noms de paramètre.

Lisibilité et réutilisation

L'écriture d'une seule ligne de commandes et de paramètres ne contribue toutefois pas à la lisibilité. Windows PowerShell vous permet d'améliorer la lisibilité des commandes que vous pouvez saisir directement dans l'application sans avoir écrire de script. Voici comment cela peut se présenter :

PS C:\> $names = get-content "c:\computers.txt"
PS C:\> foreach ($name in $names) {
>> $name
>> gwmi Win32_OperatingSystem -prop ServicePackMajorVersion -comp $name
>> }
>>

Cette fois-ci, le contenu du fichier est stocké dans la variable $names. Cet exemple utilise toujours Foreach, mais la commande n'est pas entrée via un canal, de sorte que vous devez lui indiquer les ensembles d'objets à passer en revue et la variable dans laquelle sera stocké chaque objet. Il s'agit de la partie qui contient : ($name in $names). Tout le reste est à peu près similaire. Dès que vous appuyez sur Entrée, le code est exécuté et les résultats s'affichent.

Si vous souhaitez répéter le même code, il vous suffit d'en faire une fonction. Entrez de nouveau le code directement dans l'environnement :

PS C:\> function Get-ServicePacks ($file) {
>> $names = get-content $file
>> foreach ($name in $names) {
>> $name
>> gwmi win32_operatingsystem -prop servicepackmajorversion -comp $name
>> }
>> }
>>

Comme vous pouvez le voir, rien n'a vraiment changé. L'exemple précédant est tout simplement repris dans une fonction appelée Get-ServicePacks (qui conserve la convention de nom verbe/nom de Windows PowerShell). La fonction a maintenant le paramètre d'entrée "$file" qui a été substitué dans la cmdlet Get-Content, de sorte qu'un fichier différent peut être spécifié lorsque la fonction est exécutée. À présent que la fonction est définie, exécutez-la tout simplement en appelant son nom, pratiquement comme une cmdlet, puis en transférant le paramètre d'entrée :

PS C:\> Get-ServicePacks c:\computers.txt

La figure 2 illustre les résultats.

L'inconvénient est que cette fonction n'existera que le temps pendant lequel cette instance de Windows PowerShell est exécutée. Une fois que vous fermez l'application, la fonction est supprimée. Vous pouvez copier la fonction dans votre profil Windows PowerShell, qui est une sorte de script qui s'exécute automatique à chaque démarrage de Windows PowerShell. En procédant ainsi, la fonction sera disponible dans chaque fenêtre Windows PowerShell que vous ouvrez. Ou, si vous le souhaitez, vous pouvez définir la fonction dans un script autonome, que vous pouvez ensuite exécuter simplement en entrant le chemin du script et le nom de fichier.

Figure 2 Résultats de l'exécution de la fonction Get-ServicePacks

Figure 2** Résultats de l'exécution de la fonction Get-ServicePacks **

Le monde est un fichier (ou un dossier)

Windows PowerShell, c'est bien plus que des fonctions et des cmdlets. Attardons-nous sur la gestion de fichiers pour illustrer rapidement les autres fonctionnalités offertes par Windows PowerShell . La navigation dans les dossiers et les lecteurs dans Cmd.exe n'a sans doute plus aucun secret pour vous : vous tapez « C » pour accéder au lecteur C et "cd \test" pour passer dans le dossier C:\Test. Windows PowerShell fonctionne exactement de la même manière, bien que cd est simplement un alias de la cmdlet Set-Location.

Essayez d'exécuter Get-PSDrive, la cmdlet qui répertorie tous les lecteurs disponibles. Outre les lecteurs C:, D: et éventuellement A:, vous en trouverez également un nommé « Cert », un autre nommé « Env » et enfin deux autres nommés « HKCU » et « HKLM ». Windows PowerShell fait réellement preuve de nombreux types de ressources de stockage sous forme de « lecteurs », semblables à des magasins de certificats, à des variables d'environnement et à un registre, tous disponibles dans un environnement comparable à une interface de navigation par fichiers habituelle.

Passez à la ruche de registre HKEY_LOCAL_MACHINE en saisissant Set-Location HKLM : (ou cd hklm : si vous préférez le raccourci), puis appuyez sur Entrée. Exécutez ensuite cd software\microsoft pour passer dans la clé SOFTWARE\Microsoft. Vous pouvez utiliser dir (un alias de la cmdlet Get-ChildItem) pour répertorier les sous-clés dans cette portion du registre. Si vous souhaitez supprimer une clé, utilisez del pour la supprimer comme s'il s'agissait d'un fichier ou d'un dossier. (Soyez très prudent, de graves problèmes peuvent se produire si vous supprimez les clés requises ou si vous modifiez le registre de façon incorrecte.)

Toute cette souplesse provient des fournisseurs qui mettent en correspondance les ressources (comme le registre et le magasin de certificats) dans un format qui ressemble à un système de fichiers. Microsoft prévoit d'étendre Windows PowerShell en ajoutant des fournisseurs, pour vous permettre, par exemple, de naviguer dans un magasin Exchange Server comme dans un système de fichiers. Il s'agit d'une technique très importante. Elle utilise la grande variété de référentiels utilisés par Windows et les fait tous apparaître de façon identique. Par ailleurs, elle permet de les gérer via un système de commandes et des procédés que vous connaissez déjà bien.

Conçu pour la sécurité

J'ai déjà mentionné le fait que la conception de Windows PowerShell tient compte des aspects liés à la sécurité. La première caractéristique de sécurité de Windows PowerShell est constituée par sa politique d'exécution. Par défaut, cette politique est définie sur Restreint, ce que vous pouvez vérifier en exécutant la cmdlet Get-ExecutionPolicy. En mode Restreint, les scripts ne sont pas exécutés. Point. Comme il s'agit du mode par défaut, Windows PowerShell ne peut pas être utilisé pour exécuter des scripts prêts à l'emploi.

Vous pouvez spécifier d'autres modes en utilisant la cmdlet Set-ExecutionPolicy. Personnellement, je préfère le mode RemoteSigned. Ce mode permet d'utiliser les scripts locaux (mais pas les scripts distants) sans qu'il soit nécessaire d'appliquer une signature numérique, ce qui permet de développer et tester des scripts avec beaucoup de facilité. Le mode AllSigned exécute uniquement les scripts dotés d'une signature numérique, au moyen d'un certificat délivré par un éditeur de confiance. Enfin, la stratégie Non restreinte exécute tout. Je la déconseille fortement, car elle laisse Windows PowerShell exécuter des scripts malveillants qui ont pu accéder à votre ordinateur. Notez que la stratégie d'exécution peut également être commandée par la stratégie de groupe, qui remplace tout paramètre local. (Set-ExecutionPolicy vous préviendra si les paramètres d'une stratégie de groupe remplacent vos paramètres locaux.)

En outre, Windows PowerShell n'exécutera pas les scripts de votre répertoire actuel, sauf si vous spécifiez le chemin. Cela doit permettre d'éviter tout piratage de commande. Imaginez que quelqu'un crée un script appelé IPConfig.ps1 (PS1 est l'extension des fichiers script Windows PowerShell). S'il était possible d'exécuter des fichiers en dehors du dossier actuel, vous risqueriez de taper ipconfig et d'exécuter le script créé par cet utilisateur, alors que vous aviez en fait l'intention d'exécuter le programme Windows Ipconfig.exe. Comme Windows PowerShell n'exécute pas les scripts en dehors du dossier actuel, cette erreur est impossible. Mais si vous souhaitez exécuter un script en dehors du dossier actuel, il suffit de spécifier le chemin : .\myscript, par exemple. Grâce à cette référence explicite au dossier actuel, vous êtes sûr d'exécuter un script et non une commande shell.

Windows PowerShell inclut également des fonctionnalités permettant d'améliorer la sécurité des tests. Par exemple, envisagez (mais s'il vous plaît, sans essayer) cet inquiétant cas de figure :

Get-Process | Stop-Process

La cmdlet Get-Process crée un ensemble d'objets de processus et les transfère vers la cmdlet Stop-Process, qui va vraiment les interrompre ! Cette action entraîne l'affichage, au bout d'environ cinq secondes, d'un écran bleu d'erreur STOP, car des processus Windows essentiels sont supprimés. Mais il est possible de voir ce qui se produira sans que cela se produise vraiment, en ajoutant le paramètre très pratique Whatif :

Get-process | Stop-Process -Whatif

L'exécution de ce paramètre dans Windows PowerShell entraîne la production d'un flot de déclarations, indiquant quelles auraient été les conséquences de l'utilisation de ces cmdlets, sans que vous les ayez vraiment activées. Le système d'aide en ligne de Windows PowerShell (accessible grâce à l'alias d'aide) ne décrit pas encore le paramètre Whatif, mais pensez-y. Il s'agit d'un outil précieux pour tester les scripts et les cmdlets, sans pour autant risquer des dommages ou perturbations potentielles.

Conclusion

Parmi les caractéristiques non incluses dans cette version de Windows PowerShell, la plus importante est peut-être le support de Active Directory® Services Interface (ADSI). Tandis que Windows PowerShell peut utiliser les classes .NET très robustes qui fonctionnent avec Active Directory et d'autres services d'annuaire, elle ne dispose pas encore d'une cmdlet Get-ADSIObject appropriée. En conséquence, il est un peu difficile de travailler avec des objets d'annuaire.

De même, Windows PowerShell propose souvent de nombreuses méthodes différentes pour exécuter la même tâche. C'est avantageux, mais cela peut compliquer l'apprentissage de Windows PowerShell car pour une tâche donnée, vous pouvez voir s'afficher une demi-douzaine d'exemples de méthodes.

Cela sera corrigé à terme et l'équipe Windows PowerShell continuera d'ajouter des fonctionnalités au produit. Pour rester dans la boucle, visitez le blog de l'équipe.

Don Jones est le fondateur de ScriptingAnswers.com et le co-auteur de Windows PowerShell : TFM (SAPIEN Press, 2006). Vous pouvez le contacter à l'adresse suivante :don@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.