Introduction à PowerShell (nom de code Monad)

Laurent Dardenne

Cet article vous propose de découvrir PowerShell, nom de code Monad, qui est le futur Shell de Microsoft Windows.
Les concepts de base présentés ici sont stabilisés, mais il se peut que certains détails d'implémentation ou de syntaxe diffèrent dans la release 1.0.
Je tiens à remercier Guy Métayer pour ses corrections orthographiques. ♪

- Titre : Introduction à PowerShell (nom de code Monad)

- Auteur : Laurent Dardenne

- Parution : 25 mai 2006

- Licence :

Sommaire

- I. Public concerné

- I-A. Les prérequis

- I-B. Les sources

- I-C. Détails de la documentation US de PowerShell RC1

- I-C-1. Documentation associée

- I-D. Obtenir de l'aide.

- II. PowerShell qu'est-ce que c'est ?

- III. Le socle technique

- III-A. Qu'est-ce qu'un Cmdlet

- III-A-1. Les paramètres

- III-B. Principe de nommage des Cmdlets

- III-B-1. Substantif (Nom)

- III-B-2. Verbe

- III-C. Les providers

- III-C-1. ObjectSpace

- III-D. Le pipelinening

- III-E. PowerShell et WMI

- III-F. L'affichage sur la console

- IV. Les alias

- V. Les objets COM sous PowerShell

- VI. Format de données

- VII. L'extension de type (ETS)

- VIII. Intégration d'un nouveau Cmdlet

- IX. Configuration de la sécurité

- X. La notion de 'globbing'

- XI. Raccourcis clavier

- XII. Liens

I - Public concerné

Testé avec Monad beta3 et PowerShell RC1, le Framework .NET 2.0 et Microsoft Visual Studio 2005 C# Express.
Version 1.0

I-A - Les prérequis

Des connaissances de base sur la programmation orientée objet sous .NET faciliteront la compréhension de cet article.

PowerShell nécessite les versions de Windows suivantes :

- Microsoft Windows XP SP2 ;

- Microsoft Windows Server 2003 SP1 ;

- Microsoft Windows Vista (« Longhorn »).

Les fichiers nécessaires à l'installation :
PowerShell 1.0 ;

Le Framework .NET 2.0.

I-B - Les sources

L'article au format PDF.

I-C - Détails de la documentation US de PowerShell RC1

GettingStarted.rtf : documentation sur les principes et les commandes de base.

LanguageQuickReferenceTriFold.doc : tableau récapitulatif sur le langage de script.

TracingQuickStart.doc : récapitulatif des commandes de trace.

I-C-1 - Documentation associée

Les tutoriels de la bêta 3 :

MonadScripting-HandsOnLab.doc : contient neuf exercices sur la manipulation des scripts MSH ;

BuildingMonadCmdlets-HandsOnLab.doc : tutoriel sur la construction d'un command-let ;

CreatingMonadProviders-HandsOnLab.doc : tutoriel sur la construction d'un provider pour MSH.

Le SDK de PowerShell.

Il va sans dire que la lecture de ces documents facilite grandement la compréhension du nouveau Shell et du langage de script associé.

De nombreux paragraphes de cet article sont issus de cette documentation et du SDK.

Note : jusqu'à la bêta 3 le nom du shell était Microsoft Shell, finalement il se nomme PowerShell. Vous trouverez encore de nombreux liens sous l'appellation Monad ou MSH, notamment dans le SDK.

I-D - Obtenir de l'aide.

Sous PowerShell la commande Get-Help nom_de_command-let ou Help nom_de_command-let ou encore Man nom_de_command-let permet d'afficher l'aide en ligne d'une commande particulière.
La suite de commande Get-Help nom_de_command-let|more permet un affichage par page.

II - PowerShell qu'est-ce que c'est ?

PowerShell est un langage de script et un shell interactif offrant une manière de traiter des tâches orientées commande. Les concepteurs ont suivi différentes approches afin que PowerShell soit :

- aussi interactif et composable que KSH ou BASH ;

- aussi programmable que PERL ou RUBY ;

- aussi orienté-production que VMS DCL ou AS400 CL.

PowerShell est compatible avec les précédents langages de scripting. En règle générale, PowerShell exécute tous les commandes et scripts existants. PowerShell n'interprète pas les fichiers .bat ou .cmd, il les dirige vers cmd.exe pour les exécuter.

La modification de variables d'environnement dans un script .cmd afin d'affecter l'exécution d'autres scripts n'est pas supportée dans PowerShell et c'est la seule incompatibilité à ce niveau.

PowerShell facilitera les tâches d'administration telles que la gestion du paramétrage des composants système imprimante, réseau, IE, la création de comptes utilisateur et les opérations associées…
Suite aux problèmes liés à la sécurité mis en évidence dans la Beta 1, PowerShell se base sur différents niveaux d'autorisation d'exécution. Par exemple avec le niveau AllSigned, seuls les scripts disposant d'une signature autorisée s'exécuteront.

Rien de bien nouveau, me direz-vous par rapport aux solutions existantes (Batch,VBScript,Cygwin…). Nous allons voir ça un peu plus dans le détail, ce qui vous permettra de vous faire une opinion.

III - Le socle technique

PowerShell s'appuie sur la plateforme .NET plus particulièrement sur le Framework 2.0, ce qui signifie que tout est objet sous PowerShell (aussi nommé PS).
Bien que PowerShell.exe soit un programme Win32 il est plus proche d'un loader du runtime .NET, vous pouvez utiliser le débogueur fourni avec .NET 2.0 pour confirmer que PowerShell.exe est bien une application gérée.

Déclarons une variable contenant une chaîne de caractères, puis affichons son contenu, son type et enfin le nom du type :

MSH C:\Temp> $MaVariable="Une chaîne de caractères"

MSH C:\Temp> $MaVariable
Une chaîne de caractères

MSH C:\Temp> $MaVariable.GetType()
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

MSH C:\Temp> $MaVariable.GetType().FullName
System.String

Ici GetType est une méthode de la classe .NET System.Object. On voit qu'il n'est pas nécessaire de déclarer le type de la variable pour l'utiliser ni d'appeler un constructeur pour l'initialiser, le shell se charge de ces opérations afin de nous faciliter l'écriture. Mais il est tout à fait possible d'expliciter ces opérations comme nous le verrons plus loin.

Sans rien déclarer, à part notre variable, nous accédons directement à la richesse du Framework. Toutes les classes accessibles sous .NET le sont donc sous PowerShell, sous réserve de les charger. Le langage de script ne permet pas de définir de nouvelles classes, mais permet d'enrichir une instance avec le système d'extension de type (ETS) qui n'a rien à voir avec les Extension Methods du C#3.0.
On utilisera un assembly pour déclarer de nouvelles classes.

Essayons de créer une fenêtre en appelant son constructeur par l'intermédiaire de la commande New-Object :

MSH C:\Temp> $form = new-object System.Windows.Forms.Form

Cette instruction provoque une erreur, car la classe utilisée n'est pas encore accessible, on doit donc auparavant charger l'assembly l'hébergeant :

MSH C:\Temp> [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

Où [System.Reflection.Assembly] est un nom de classe,
::LoadWithPartialName le nom d'une méthode statique effectuant le chargement et
System.Windows.Forms le nom de l'assembly hébergeant la classe Form.

Un autre aspect important concerne la manipulation des collections d'objets qui ici se fait simplement. Par exemple la commande Get-Process renvoie la liste des processus en cours d'exécution :

MSH C:\Temp> $ps=get-process
MSH C:\Temp> $ps[0]
MSH C:\Temp> $ps[0].processname

C'est le point le plus important sous PowerShell, les commandes (plus particulièrement les Cmdlet) manipulent et renvoient des instances de classes .NET. Dans une certaine mesure il n'est plus nécessaire de spécialiser les commandes puisque l'on accède à l'ensemble des informations disponibles de l'objet manipulé.

Ainsi traditionnellement dans un script, on appelait un premier programme pour récupérer le numéro de processus d'une application puis un second programme pour la supprimer. Ici sous PowerShell la méthode Kill de la classe System.Diagnostics.Process est accessible directement.

Architecture de MSH, (Monad - Task-Oriented Automation Framework,[WinHEC 2004])

Le shell Monad (msh.exe) : ligne de commande basée caractères, hébergée par le moteur de Monad.
Le moteur de Monad (msh.dll) :

- Script/Parser : traite les constructions du langage telles que les scripts, les prédicats, les conditions, etc. ;

- Pipeline Processor : gère les communications entre les Cmdlet via des pipes ;

- Command Processor : gère l'exécution des Cmdlets, l'enregistrement et les métadonnées associées ;

- Session State : gère les ensembles de données utilisés par un Cmdlet lors de son exécution ;

- Error et Event Handler : gère les exceptions et les événements ;

- Extended Type System : fournit une interface commune d'accès aux propriétés, méthodes, etc. indépendante du type d'objet sous-jacent.

Remoting (WMX): Web services for Management eXtension, remplacé par (Windows Remote Management) ?

III-A - Qu'est-ce qu'un Cmdlet

Un Cmdlet est une petite unité fonctionnelle ou tout simplement une commande comme en contiennent d'autres types de shell. Les Cmdlets diffèrent des commandes des autres environnements de scripting sur de nombreux points :

- ce sont des instances d'une classe .NET et pas de simples exécutables ;

- ils peuvent être créés avec seulement une douzaine de lignes de code ;

- en général, ils ne font pas leurs propre analyse, présentation d'erreur ou formatage d'affichage, ceux-ci sont manipulés par un moteur commun :

- des attributs sont employés pour identifier les paramètres d'entrée ou pour gérer les redirections (pipeline),

- des API sont proposées pour gérer l'affichage ou les erreurs ;

- ils manipulent et fournissent des objets, plutôt que des flux (texte), en entrée et en sortie ;

- ils sont orientés enregistrement, traitant un seul objet à la fois.

Un Cmdlet est donc du code managé et son implémentation doit respecter certains points par exemple :

- la classe doit dériver directement ou indirectement de System.Management.Automation.Cmdlet ;

- l'attribut [System.Management.Automation.Cmdlet(…)] doit être défini sur la classe ;

- une ou plusieurs des méthodes virtuelles suivantes : BeginProcessing(), ProcessRecord() et EndProcessing() doivent être surchargées.

Les Cmdlets peuvent être réalisés avec n'importe quel langage .NET ou à l'aide du langage de script PowerShell. Utilisez Get-Command pour afficher les Cmdlets disponibles.

III-A-1 - Les paramètres

Les arguments d'un Cmdlet peuvent être indiqués de différentes manières. Voyons cela avec le Cmdlet Get-Command, qui fournit des informations au sujet des divers Cmdlets disponibles. Sa signature est :

get-command -Name [string] -Type [CommandTypes] -Verb [string] -Noun [string]

Dans ce cas-ci et parce que -Name est le premier paramètre, vous pouvez omettre la désignation de paramètre (-Name) et indiquer seulement la valeur de ce paramètre :

msh> get-command get-command
Command Type    Name                      Definition
------------    ----                      ----------
Cmdlet          get-command               get-command [-Verb String[]] [-Nou...

Si vous indiquez une série de valeurs sans désigner explicitement les paramètres, PowerShell associera automatiquement les valeurs aux désignations appropriées basées sur l'ordre par défaut des paramètres indiqués par la signature de commande, ainsi si vous entrez ce qui suit :

msh> get-command A B C

PowerShell supposera que A est le paramètre -Name, B est le paramètre -Type, et C le paramètre -Verb. Si vous voulez employer les paramètres dans le désordre ou si vous souhaitez omettre des paramètres, vous pouvez indiquer la désignation de paramètre ainsi que la valeur :

msh> get-command -Verb get
Command Type    Name                      Definition
------------    ----                      ----------
Cmdlet          get-command               get-command [-Verb String[]] [-Nou...

La définition d'un paramètre d'une 'classe Cmdlet' se fait par l'intermédiaire d'un attribut placé sur un membre :

[Parameter(Mandatory=true, Position=0)]
public string[] FullName

Choisissez vos paramètres dans la liste de paramètres normalisés du SDK.

Le runtime de PowerShell fournit deux ensembles de paramètres : les paramètres communs et ceux de confirmation (ShouldProcess).

Nom de 'domaine'

Description

Exemples

Common Parameters

Les paramètres communs suivants sont présents sur tous les Cmdlets et la redéclaration de ces noms de paramètres provoquera une erreur lors de l'enregistrement du Cmdlet.

Debug, Verbose, ErrorAction,…

ShouldProcess Parameters

Les paramètres ShouldProcess suivants sont présents quand le Cmdlet implémente la méthode ShouldProcess. Quand cette méthode est implémentée, la redéclaration de ces noms de paramètres provoquera une erreur lors de l'enregistrement du Cmdlet.

Confirm (Demande la confirmation d'une action),
WhatIf (Simule l'exécution de l'action).

Activity Parameters

Paramètres utilisés pour préciser le comportement du Cmdlet.

Compress, CaseSensitive, Retry, Notify …

Date and Time Parameters

Paramètres utilisés pour manipuler l'information de date et d'heure lors d'une consultation ou création.

After, Before, Accessed.

Format Parameters

Paramètres utilisés pour le formatage ou la génération de données.

As, Binary, NewLine…

Property Parameters

Paramètres utilisés pour spécifier des propriétés du Cmdlet.

LogName, Property, Ownern…

Quantity Parameters

Paramètres utilisés pour spécifier la portée ou l'étendue d'une commande.

All, Scope, Allocation…

Resource Parameters

Paramètres utilisés pour les ressources, telles que l'assemblage qui contient la classe du Cmdlet et l'application hébergeant le Cmdlet.

Assembly, Class, Culture, Interface…

Security Parameters

Paramètres utilisés pour la sécurité, comme ceux indiquant la clé de certificat et les informations de privilèges.

ACL, CertFile, CertStoreLocation…

III-B - Principe de nommage des Cmdlets

Un Cmdlet s'appuie sur le modèle objet de .NET pour sa construction et sur le modèle verbe-substantif pour sa règle de nommage.
Toutes les commandes doivent être bien formées, un nom correct se compose d'un verbe et d'un nom sous la forme : verbe-nom.
Notez l'utilisation du caractère « - » pour séparer le verbe d'action du nom de la ressource concernée.

L'idée est que chaque nom sera employé pour opérer sur une certaine partie spécifique du système. Par exemple le nom Drive permet de désigner les divers lecteurs du système.

Les opérations, ou les actions sont définies par les verbes. Par exemple nous pourrions créer un lecteur ou retirer un lecteur existant, la syntaxe serait respectivement New-Drive et Remove-Drive.

On utilisera la commande Get-Help ou Get-Command (-Noun -Verb) pour retrouver les noms et verbes recensés :

MSH C:\Temp> get-help object # Retrouve les noms de commande comportant le mot Object
Name                              Category         Synopsis
----                              --------         --------
foreach-object                    Command          Applies script blocks to each object...
where-object                      Command          This Cmdlet filters the input from t...
compare-object                    Command          Compares the properties of objects.
measure-object                    Command          Measures various aspects of objects ...
tee-object                        Command          Sends input objects to two places.
new-object                        Command          [-TypeName] type-name
select-object                     Command          Selects objects based on parameters ...
group-object                      Command          Groups the objects that contain the ...
sort-object                       Command          Sorts the input objects by property ...
write-object                      Command          Writes an object to the pipeline

MSH C:\Temp> get-commande -Verb new # Retrouve les noms de commande comportant le verbe New

Name                              Category         Synopsis
----                              --------         --------
new-drive                         Command          Installs a new drive on the machine.
new-item                          Command          Creates a new item in a namespace
new-property                      Command          Sets a new property of an item at a ...
new-service                       Command          Creates a new service
new-securestring                  Command          Creates a SecureString object
new-alias                         Command          Creates a new Cmdlet-alias pairing
new-timespan                      Command          Creates a timespan object
new-object                        Command          [-TypeName] type-name
new-variable                      Command          Creates a new variable.

III-B-1 - Substantif (Nom)

Les noms représentent des ressources du système, ils identifient donc le type d'objet sur lequel on opère.
Pour nommer un Cmdlet choisissez des noms de substantif spécifiques et évitez l'utilisation de noms génériques, car PowerShell emploiera ces derniers pour fournir des commandes opérant sur un large éventail de ressources.

Le mieux est d'employer un nom singulier. Il est aussi recommandé de préfixer un nom générique, par exemple Server, avec une version raccourcie du nom du produit. Par exemple Get-SQLServer.

Voici la liste des noms génériques que PowerShell a réservés :

- Alias ;

- Children ;

- Command ;

- Content ;

- Drive ;

- History ;

- Item ;

- Location ;

- Object ;

- Property ;

- PropertyValue ;

- Provider ;

- RunSpace ;

- Variable.

III-B-2 - Verbe

Le verbe identifie l'action qu'un Cmdlet effectue.
Choisissez un verbe dans la liste de verbes standards du SDK et évitez de dévier de cette liste. Les concepteurs ont souhaité pouvoir effectuer 80 à 90 % des opérations sur le système en utilisant moins de 50 verbes. Ceci permet aux administrateurs d'apprendre ces 50 verbes et de deviner rapidement quelles combinaisons utiliser lorsqu'ils rencontrent un nouvel objet.

Considérons l'exemple où un utilisateur souhaite arrêter une partie du système : Processus, services, WebServices, job de sauvegarde, etc.

Choisissons de normaliser les commandes autour du verbe Stop. Les commandes seraient donc Stop-Process, Stop-Service, Stop-WebService, Stop-BackupJob, etc.
Notez que la volonté de tout contrôler avec moins de 50 verbes nécessite quelques décisions difficiles. Kill est traditionnellement le verbe pour supprimer un processus, Cancel possède une nuance qui est différente de l'arrêt (Stop), Terminate pourrait être plus approprié pour certaines parties du système. Toutes ces considérations jouent un rôle important si on regarde juste un nom simple, mais il faut passer outre pour offrir un système d'administration cohérent.

Les paramètres peuvent être utilisés pour préciser le sens d'un verbe. Par exemple Stop-WebService -Drain pourrait être employé pour indiquer que des opérations doivent être accomplies sur certains éléments avant d'arrêter le service (la création d'une nouvelle commande comme Drain-WebServices n'est pas nécessaire).

Les verbes ont été regroupés par paire pour faciliter leur mémorisation, par exemple Start est associé à Stop, Get à Set…

Ces regroupements sont :

Common Object Verbs

Certains de ces derniers seront employés avec presque chaque nom.
Par exemple beaucoup de noms supporteront les verbes New, Remove.

Data verbs

Ceux-ci sont employés pour les traitements des données.
Par exemple Compare et Merge.

Lifecycle verbs

Ceux-ci concernent l'activité d'un Cmdlet.
Les verbes de cycle de vie incluent Start, Stop et Resume.

Diagnostic verbs

Spécifie des opérations de diagnostics.
L'ensemble inclut Measure, Test et Debug.

Communications verbs

Spécifie des opérations de communications.
Par exemple Send et Receive.

Security Verbs

PowerShell utilise cet ensemble pour définir les verbes à appliquer à la sécurité.
Par exemple Grant et Revoke.

L'utilisation de ces verbes lors de la création d'un Cmdlet permettra aux utilisateurs de déduire qu'un Cmdlet supportant Start proposera probablement Stop et peut-être d'autres verbes de ces ensembles.

Notez que dans la plupart des cas un nom emploiera des verbes de plus d'un ensemble. En même temps la plupart des noms n'emploieront pas tous les verbes d'un ensemble.

Suite aux retours des bêta-testeurs l'équipe du projet Monad a fait en sorte que les développeurs utilisant des verbes non standards soient forcés d'ajouter « __ » au début du nom de Cmdlet afin de rendre leur Cmdlet utilisable.

III-C - Les providers

PowerShell vous offre la possibilité d'employer un ensemble cohérent de Cmdlets pour parcourir et naviguer sur différents types de structure de données telles que le système de fichiers, la base de registre, Active Directory ou WMI.
Par exemple, vous pouvez employer la même commande pour lister les dossiers d'un répertoire ou énumérer le contenu d'une clé de la base de registre.

Affichons le répertoire courant :

MSH C:\Temp> dir *.tmp
Directory: Microsoft.Management.Automation.Core\FileSystem::C:\Temp

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        08/04/2006     17:58            SIT19021.tmp
-a---        07/04/2006     09:17        256 ZLT04666.TMP
-a---        10/04/2006     13:16      98304 ~DF2530.tmp

Modifions le provider courant pour celui de la base de registre :

MSH C:\Temp>  set-location hklm:
MSH HKLM:\> dir HARDWARE
Hive: Microsoft.Management.Automation.Core\Registry::HKEY_LOCAL_MACHINE\HARDWARE

SKC  VC Name                           Property
---  -- ----                           --------
4   0 ACPI                           {}
1   0 DESCRIPTION                    {}
6   0 DEVICEMAP                      {}
3   0 RESOURCEMAP                    {}

Les providers du shell sont des interfaces logicielles qui présentent le contenu des différentes structures de données dans un format cohérent.
Un provider du shell n'est pas lui-même la structure de données, mais une manière d'accéder aux structures de données au travers des Cmdlets du noyau.
Quand un provider rend disponibles des structures de données, il le fait en créant un ou plusieurs lecteurs (drive) qui semblent contenir toutes ou certaines données stockées.

Par exemple, dans le cas du provider du système de fichiers, il crée un lecteur pour chaque disque de votre système. En conséquence, si vous avez un lecteur C et un lecteur D, le provider du système de fichiers créera des lecteurs PowerShell appelés C et D. En fait, toutes les fois qu'un nouveau lecteur est créé par Windows, y compris un lecteur partagé sur un serveur, le provider du système de fichiers crée un lecteur PowerShell avec le même nom.

Pour visualiser tous les lecteurs disponibles actuellement dans PowerShell, utilisez la commande suivante :

MSH C:\Temp> get-drive
Name       Provider      Root                  CurrentLocation
----       --------      ----                  ---------------
A          Microsoft.... A:\
Alias      Microsoft....
C          Microsoft.... C:\                   Temp
cert       Microsoft.... \
D          Microsoft.... D:\
E          Microsoft.... E:\
Env        Microsoft....
F          Microsoft.... F:\
Function   Microsoft....
HKCU       Microsoft.... HKEY_CURRENT_USER
HKLM       Microsoft.... HKEY_LOCAL_MACHINE
Variable   Microsoft....

Vous pouvez visualiser les Cmdlets du noyau par la commande Get-Help about_Core_Commands.

hosting application

Image issue du SDK de PowerShell.

Note
Il est tout à fait possible d'appeler des scripts ou des Cmdlets dans vos applications (pour plus de détails).

III-C-1 - ObjectSpace

Un espace d'objet est un ensemble d'objets organisés en hiérarchie. Cette hiérarchie est appelée un Drive.
La hiérarchie est composée d'un ensemble de positions identifiées par des chaînes de caractère appelées Path.
La syntaxe pour localiser une position précise est « Drive:Path ».
Il peut y avoir à chaque position un ou plusieurs des éléments suivants : Children, Item, Property, Content, Permission, Relation.

Ce modèle ne normalise pas, pour aucun de ces éléments, la syntaxe d'un chemin ou des structures de données. Les propriétés et le contenu d'une position dans la base de registre sont très différents de ceux d'un système de fichiers ou d'un document XML ou encore d'un chemin Active Directory.
Notez que les chemins peuvent être relatifs ou absolus.

III-D - Le pipelinening

PowerShell favorise l'interaction avec les données du système qui sont sous forme de données structurées ou d'objets. On peut, en ligne de commande, référencer les propriétés de ces objets en utilisant leur nom plutôt que d'indiquer des colonnes et des lignes. Il en résulte un shell qui est nettement plus simple à employer parce qu'il permet à l'utilisateur de se concentrer sur ce qu'il veut réaliser au lieu de la façon dont il doit les réaliser.

C'est cette dernière approche que l'on trouve avec les batchs existants, voici un exemple (sous NT-W2K) pour récupérer la date système dans une variable :

echo off
rem Insère la date système dans une variable

rem Récupère la date. Le paramètre /T renvoie une ligne contenant 2 "mots"
rem  le premier = le nom du jour
rem  le second = la date
rem On place donc le deuxième dans la variable
for  /f "tokens=1-2 " %%A in ('Date /T') do set date=%%B

rem Le séparateur de format de date par défaut est "/"
rem ce caractère est interdit dans les noms de fichier.
rem On utilise ce caractère séparateur pour parser la date JJ MM YYYY
rem Enfin on reconstruit la date avec le nouveau séparateur
rem On peut utiliser la variable DATE comme nom de fichier.
rem Attention on code la date sur 10 caractères (2+1+2+1+4)
rem SOUS XP DATE=jj/mm/aaaa
for  /f "tokens=1-3 delims=/" %%A in ('echo ?TE%') do set date=%%A-%%B-%%C

qui devient sous PowerShell :

MSH C:\Temp> $Date=get-date -uformat "%d-%m-%y"

De plus, PowerShell « ne lie pas » l'acquisition de données avec la manipulation et l'affichage de données. PowerShell est construit de telle manière que les données transitent d'une commande à une autre sans être transformées au format texte. C'est seulement quand le texte est nécessaire qu'une conversion de l'objet est faite.

Par exemple, si nous voulions une liste de tous les processus dont le nombre de handle est plus grand que 400, nous exécuterions ce qui suit :

MSH C:\Temp> Get-Process | where { $_.handlecount -gt 400 } | Format-List

Dans cet exemple, le Cmdlet Get-Process passe des objets au Cmdlet Where-Object qui sélectionne les objets qui ont une propriété appelée handlecount et d'une valeur supérieure à 400. Le Cmdlet Where-Object envoie alors ces objets au Cmdlet Format-List qui les affiche.

La suite de caractères $_ représente l'instance de l'objet courant renvoyé par le pipe. PowerShell propose de nombreuses variables spéciales, voir le chapitre Special Variables du document intitulé GettingStarted.rtf.

Un pipeline spécial est disponible pour remonter les erreurs qui peuvent être bloquantes ou pas, dans ce dernier cas le traitement se poursuit après l'affichage d'un message d'erreur. Le Cmdlet Write-Error écrit sur ce pipeline d'erreur.

III-E - PowerShell et WMI

L'accès à WMI est aussi simple que sous VBScript/WSH. PowerShell s'appuie sur le référentiel WMI afin d'accéder aux ressources physiques sans avoir à recoder tous les traitements plus ou moins fastidieux au travers d'API .NET.
Par exemple pour afficher l'espace libre disponible sur un disque on utilisera la commande Get-WmiObject sur la classe win32_logicaldisk :

get-wmiobject win32_logicaldisk|format-table deviceid,size,freespace

III-F - L'affichage sur la console

De nombreux Shell utilisent l'instruction Echo pour écrire du texte vers un pipe, sur la console, etc.
PowerShell adopte une approche légèrement différente en différenciant le pipe et la console. Le résultat n'est pas converti en texte tant qu'il n'est pas destiné à l'utilisateur. Le Cmdlet Write-Host est équivalent à la commande UNIX Echo … > /dev/tty.

Si vous voulez écrire un objet dans un pipe, vous pouvez soit employer la commande Write-Host, soit employer l'objet lui-même. PowerShell enverra automatiquement cet objet dans le pipe.

Si vous voulez communiquer directement avec l'utilisateur, utilisez la commande Write-Host. En raison de cette différence, l'alias pour Echo est Write-Object, ainsi il peut être employé pour envoyer le prochain élément dans un pipe ou sur la console.

Notez que Write-Host ne peut pas être redirigé.

IV - Les alias

Un alias est un raccourci d'un Cmdlet ou d'un exécutable, mais sans ces paramètres (dans la bêta 3 tout du moins). Ils peuvent faciliter l'accès à un exécutable ou associer un terme plus explicite à un Cmdlet. Par exemple la commande DIR est un alias du Cmdlet Get-ChildItem.

La commande Alias permet de retrouver la liste des alias déclarés. Utilisez Help Alias pour afficher les commandes de manipulation d'alias.

V - Les objets COM sous PowerShell

Les objets COM peuvent être instanciés par la commande New-Object en précisant le paramètre -com.

$app = new-object -com "Excel.Application"
$Excel = get-process "EXCEL"
$Excel.Close

VI - Format de données

PowerShell propose différents formats de présentation des données, par exemple XML :

#Lignes en commentaire
#Exporte les données au format XML
get-process|Export-clixml MesProcess.XML

#Récupère le contenu du fichier dans une variable
$a=get-content MesProcess.xml

Voici le contenu du fichier créé :

<Objs Version="1.1" xmlns="http://schemas.microsoft.com/msh/2004/04">
<Obj RefId="RefId-0">
<TN RefId="RefId-0">
<T>System.Diagnostics.Process</T>
<T>System.ComponentModel.Component</T>
<T>System.MarshalByRefObject</T>
<T>System.Object</T>
</TN>
<Props>
<I32 N="BasePriority">8</I32>
<B N="HasExited">false</B>
<S N="Handle">3152</S>
<I32 N="HandleCount">101</I32>
<I32 N="Id">2924</I32>
<S N="MachineName">.</S>
....

Vous pouvez utiliser les commandes Format-Table et Format-List pour manipuler le format CVS par exemple.

VII - L'extension de type (ETS)

Le système d'extension de type (ETS) fournit aux développeurs de Cmdlets et de scripts un mécanisme d'accès uniforme leur permettant de manipuler facilement les différents objets qui transitent entre les Cmdlets, les fonctions, les filtres et les scripts.
En utilisant ETS, les développeurs de Cmdlets et de scripts peuvent manipuler des objets .Net et des données structurées en utilisant la même syntaxe que celle employée par des classes du CLR.

Le langage de script de PowerShell n'est pas typé (typeless), car une variable n'a pas besoin d'être déclarée dans un type particulier. Ceci signifie que les variables créées par un développeur sont par nature sans type. Cependant, le système de PowerShell est piloté par les types (type-driven) parce qu'il dépend des noms de type pour fonctionner.
Par conséquent un développeur de script a besoin de la capacité d'énoncer le type d'une de ses variables et de construire ses propres ensembles d'objets dynamiquement typés qui contiennent des propriétés et des méthodes et pouvant participer au système piloté par les types. ETS résout ce problème en fournissant un objet commun au langage de script qui a la capacité d'énoncer son type dynamiquement et d'ajouter des membres dynamiquement.

Dans certains cas ce système sera utilisé pour créer un alias de propriété sur une classe particulière afin d'homogénéiser l'accès aux données identiques, mais nommées différemment.
Par exemple certaines collections .NET possèdent une propriété nommée length pour déterminer le nombre d'éléments de la collection alors que d'autres ont une propriété nommée Count. Dans ce cas pour faciliter la manipulation de cette information on ajoutera dans le fichier Types.ps1xml l'extension suivante :

<Type>
<Name>System.Array</Name>
<Members>
<AliasProperty>
<Name>Count</Name>
<ReferencedMemberName>Length</ReferencedMemberName>
</AliasProperty>
</Members>
</Type>

Cet exemple étend le type System.Array. L'affichage des membres du type renvoie désormais :

MSH> Get-Member -inputobject (1,2,3,4)

TypeName: System.Object[]

Name               MemberType    Definition
----               ----------    ----------
Count              AliasProperty Count = Length
...
Length             Property      System.Int32 Length {get;}

Note
Ce mécanisme d'extension est possible, car chaque objet que vous employez est encapsulé dans une instance de la classe System.Management.Automation.PSObject.

MSH> $a=Dir
MSH> $a.MshObject
...

Pour plus de détails, consultez le SDK ou le document nommé GettingStarted.rtf.

VIII - Intégration d'un nouveau Cmdlet

L'intégration d'un nouveau Cmdlet se fait soit à l'aide du programme Make-Shell.exe soit à l'aide du mécanisme appelé PSSnapIn.
Make-Shell construit un nouveau shell en intégrant les Cmdlets que vous avez créés. Ceci permet d'avoir plusieurs types de shell dédiés à la gestion des SGBDR, des services Web, etc. Notez que le shell primaire ne peut être modifié.

L'interopérabilité entre différentes instances de PowerShell ne semble pas encore implémentée.

La commande suivante crée un Shell (exécutable) nommé newshell qui intègre le Cmdlet Get-String défini dans l'espace de nom PDC.Demos.

make-shell -out newshell -namespace PDC.Demos -reference get-string.dll

Il existe une autre possibilité d'extension du shell avec le Cmdlet PSSnapIns. Consultez la documentation de PowerShell pour plus de détails.

L'utilitaire Make-Shell est disponible dans le SDK Windows Vista.

IX - Configuration de la sécurité

PowerShell intègre la vérification des scripts avant leur exécution. La politique de sécurité appliquée aux scripts ou à toutes autres commandes saisies devant être exécutée est régie par la clé de registre suivante :

HKLM\Software\Microsoft\msh\ShellId\ExecutionPolicy

Valeur

Description

Restricted

Valeur par défaut. Niveau de sécurité maximum, aucune exécution de script, accès interactif uniquement et charge uniquement les fichiers de configuration signés dont la signature a été approuvée.

AllSigned

Tous les fichiers .ps1 et .ps1xml doivent être signés numériquement. Si un fichier signé est exécuté, le shell vous demandera de confirmer si l'éditeur de la signature est autorisé ou non à exécuter ce fichier.

RemoteSigned

Seuls les fichiers .ps1 et .ps1xml provenant d'Internet doivent être signés numériquement. Si un fichier signé issu d'Internet est exécuté, le shell affichera un message d'avertissement demandant confirmation avant son exécution.

Unrestricted

Aucun fichier ne doit être signé. Si un fichier provient d'Internet, le shell affichera un message d'avertissement demandant confirmation avant son exécution. Pour supprimer ce message d'avertissement, faites dans l'explorateur de Windows, un clic droit sur le fichier, puis « propriétés » et enfin « débloquer ».

Pour d'autres informations, consultez l'aide en ligne :

get-help about_signing|more

X - La notion de 'globbing'

Le globbing est le développement de caractères spéciaux de remplacement tels que *, ? ou [] utilisés dans une expression.
Cette notion est similaire aux expressions régulières qui elles sont accessibles via le Framework.

Prenons la commande suivante :

MSH> gps [a-c]*,[t-z]* -exclude *[d-t] | stop-process

On arrête ici les process dont le nom commence par abc et tuvwxyz sauf ceux dont le nom finit par les lettres de d à t.
Les shells traditionnels traitent le globbing sur des noms de dossier. Ici comme on travaille sur des objets et leurs propriétés nous avons un nombre de possibilités extraordinairement riches concernant le traitement de remplacement de caractères.

XI - Raccourcis clavier

La version actuelle est assez pauvre en raccourcis-clavier espérons que la version 1.0 soit mieux fournie.

Touches de Fonction

Escape annule la saisie en cours.
F1 recopie caractère par caractère la dernière commande.
F2 copie jusqu'au caractère n°.
F3 affiche la dernière commande.
F4 supprime jusqu'au caractère n°.
F5 parcourt les dernières commandes vers le début comme la touche 'flèche vers le haut'.
F6 équivaut à la saisie de control ^Z (fin de fichier ASCII).
F7 liste dans une fenêtre les dernières commandes saisies.
F8 parcourt les dernières commandes vers la fin comme la touche 'flèche vers le bas'.
F9 numéro de commande, cf. F7.

Autres touches

haut de page première commande.
bas de page dernière commande.
tab complétion. c:\te + Tab complète avec le prochain nom fourni par le provider. Tab sans saisie affiche la première entrée fournie par le provider courant.
control-C annule la ligne.
+-!, passe en mode saisie de bloc.
} une accolade fermante suivie de deux retours chariot revient en mode 'commande'.

XII - Liens

msh_Scriptomatic, générateur de script.

POWERSHELL ANALYZER RC1, projet autour de PowerShell.

A guided tour of the Microsoft Command Shell (Article très fourni).

Chapitre d'introduction du livre intitulé « Monad » chez OReilly (US).

Un jeu en PowerShell en mode caractères.

PowerShell et le remoting (PowerShell ne supporte pas pour le moment le remoting).

Providers pour Visual Source Safe et SharePoint 2003 sur le site Codeplex.com.