Les Fonctions Et Scripts Avancees Sous Power Shell Version 2

download Les Fonctions Et Scripts Avancees Sous Power Shell Version 2

of 67

Transcript of Les Fonctions Et Scripts Avancees Sous Power Shell Version 2

PowerShell version 2 : Les fonctions avances.Par Laurent Dardenne, le 13 mars 2010.

Niveau

La version 2 de PowerShell apporte de nombreuses volutions, lune concerne lcriture de cmdlet en code natif laide de fonctions dites avances utilisant diffrents types dattributs. Dans le texte suivant je vous propose dtudier la cration de cmdlets sans utiliser de langage compil dotnet. Une bonne connaissance des principes de base de PowerShell, notamment celui du pipeline, du fonctionnement des cmdlets et des classes dotnet, facilitera la lecture de ce tutoriel qui est tout de mme orient dveloppeur. Difficile de faire autrement sur un tel sujet, mais cela reste un tutoriel sur le scripting avanc sous PowerShell. Merci Thomas Garcia pour sa relecture et ses corrections orthographiques.Les fichiers sources : ftp://ftp-developpez.com/laurent-dardenne/articles/Windows/PowerShell/Les-fonctions-etscripts-avancees-sous-PowerShell-version-2/fichiers/Les-fonctions-et-scripts-avancees-sousPowerShell-version-2.zip Test avec PowerShell V2 sous Windows XP sp3. Site de lauteur : http://laurent-dardenne.developpez.com/

Laurent Dardenne, libre de droits pour tous les usages non commerciaux.

Page 1 / 67

Chapitres1 QUELLES SONT LES AVANCEES ?.............................................................................................................4 1.1 PRINCIPE DUN ATTRIBUT ............................................................................................................................5 1.2 LES TYPES DATTRIBUT DE PARAMETRE ......................................................................................................5 1.2.1 Attribut Alias..........................................................................................................................................5 1.2.2 Attributs de validation de paramtres....................................................................................................6 1.2.3 Attribut Parameter.................................................................................................................................6 1.3 DECLARER UN ATTRIBUT .............................................................................................................................6 2 LIAISON DE PARAMETRES .........................................................................................................................8 2.1 3 CONVENTION DE NOMMAGE DE PARAMETRES ...........................................................................................10

LA GESTION DU PIPELINE ........................................................................................................................11 3.1 DIFFERENCES ENTRE LA VERSION 1 ET LA VERSION 2 ................................................................................12

4

LES ARGUMENTS DE LATTRIBUT PARAMETER ..............................................................................16 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.7.1 4.7.2 MANDATORY.............................................................................................................................................16 POSITION ...................................................................................................................................................16 HELPMESSAGE ..........................................................................................................................................17 VALUEFROMPIPELINE ...............................................................................................................................17 VALUEFROMPIPELINEBYPROPERTYNAME ...............................................................................................17 VALUEFROMREMAININGARGUMENTS ......................................................................................................21 PARAMETERSETNAME ..............................................................................................................................21 Validit des jeux de paramtres...........................................................................................................23 Lattribut OutputType ..........................................................................................................................25

5

LES ATTRIBUTS DE VALIDATION...........................................................................................................26 5.1 ALLOWNULL .............................................................................................................................................28 5.2 VALIDATENOTNULL .................................................................................................................................28 5.3 ALLOWEMPTYSTRING ...............................................................................................................................29 5.4 VALIDATENOTNULLOREMPTY .................................................................................................................29 5.5 ALLOWEMPTYCOLLECTION ......................................................................................................................29 5.6 VALIDATECOUNT ......................................................................................................................................30 5.7 VALIDATELENGTH ....................................................................................................................................30 5.8 VALIDATEPATTERN...................................................................................................................................31 5.9 VALIDATERANGE ......................................................................................................................................31 5.10 VALIDATESET ...........................................................................................................................................31 5.11 VALIDATESCRIPT ......................................................................................................................................32 5.11.1 Cration de rgles de validation .....................................................................................................33 5.11.2 Usage de fonction de validation dans un module............................................................................34 5.12 DIFFERENCES DE COMPORTEMENT ENTRE UNE FONCTION AVANCEE ET UN CMDLET .................................36

6 7

CREATION DE PARAMETRES DYNAMIQUES ......................................................................................36 LA VARIABLE AUTOMATIQUE PSCMDLET .........................................................................................42 7.1 7.2 7.3 GESTION DES EXCEPTIONS .........................................................................................................................43 LA VARIABLE ERRORVIEW ........................................................................................................................45 PROPOS DU BLOC END ............................................................................................................................45

8

LES ARGUMENTS DE LATTRIBUT CMDLETBINDING .....................................................................46 8.1 SUPPORTSSHOULDPROCESS ......................................................................................................................46 8.1.1 propos des capacits des providers ..................................................................................................47 8.1.2 La mthode ShouldContinue ................................................................................................................48

Laurent Dardenne, libre de droits pour tous les usages non commerciaux.

Page 2 / 67

8.2 CONFIRMIMPACT .......................................................................................................................................50 8.2.1 La variable $ConfirmPreference .........................................................................................................50 8.2.2 La variable $WhatIfPreference............................................................................................................51 8.3 SUPPORTSTRANSACTIONS .........................................................................................................................52 8.4 DEFAULTPARAMETERSETNAME ...............................................................................................................52 9 ACCEDER AUX DETAILS DUNE COMMANDE.....................................................................................52 9.1 9.2 9.3 9.4 9.5 10 ACCEDER AUX INFORMATIONS DUNE FONCTION ......................................................................................52 ACCEDER AUX INFORMATIONS DUN CMDLET ...........................................................................................55 ACCEDER AUX INFORMATIONS DUN FICHIER SCRIPT ................................................................................56 ACCEDER AUX INFORMATIONS DUN MODULE ...........................................................................................56 UNE APPROCHE DU SCRIPTING BASEE SUR DES PLUG-INS ...........................................................................57

PROXY DE CMDLET ....................................................................................................................................57 10.1 STEPPABLE PIPELINES ...............................................................................................................................59 10.1.1 Bloc Begin.......................................................................................................................................59 10.1.2 Bloc Process....................................................................................................................................60 10.1.3 Bloc End..........................................................................................................................................60 10.2 GESTION DES ERREURS ..............................................................................................................................61 10.3 SUPPRESSION DE PARAMETRES ..................................................................................................................62 10.4 AJOUT DE PARAMETRES ............................................................................................................................62

11 12

SCRIPTBLOCK ET ATTRIBUTS ................................................................................................................63 CONSTRUIRE LAIDE EN LIGNE..............................................................................................................64 12.1 CONSTRUIRE UN FICHIER DAIDE LOCALISE AU FORMAT MAML ..............................................................64

13 14

LIENS................................................................................................................................................................66 CONCLUSION.................................................................................................................................................67

Laurent Dardenne, libre de droits pour tous les usages non commerciaux.

Page 3 / 67

1 Quelles sont les avances ?Les fonctions et scripts dits avancs sont des fonctions ou des scripts autorisant lusage dattributs comme on en utilise dans les dclarations de cmdlets cods avec un langage dotnet compil. Ainsi, on peut nativement placer des rgles de validation et des contraintes sur tout ou partie des paramtres. Nous verrons galement que certains amliorent la prise en charge des valeurs de paramtres provenant du pipeline. Avec cette version il est dsormais possible de grer tous les paramtres communs (Whatif, ErrorAction,) sans avoir coder une seule ligne de code, ou encore dintgrer laide dans le code source des fonctions ou des scripts. Elle permet galement de crer des proxys de cmdlet et dorganiser votre code laide de module. Mais commenons par le commencement et avant daller plus loin voyons les termes de paramtre et dargument. Pour linstruction :Get-ChildItem -Path C:\Temp Recurse

-Path est un paramtre et C:\temp son argument. Recurse est un switch qui ne ncessite pas dargument. Le runtime PowerShell, au travers des attributs, nous dcharge dune grande partie de la gestion des paramtres dun script ou dune fonction, lobjectif tant de proposer un comportement semblable celui dun cmdlet tout en facilitant lcriture du code. A lorigine lusage de ces attributs est de contrler les paramtres dun cmdlet cod dans un langage dotnet. Un exemple dutilisation en C# :[Parameter(Position = 0)] public string Name { get { return processName; } set { processName = value; } } private string processName;

Ici on prcise que le paramtre Name se trouve en position zro. Ainsi, lappel suivant ne ncessite pas de prciser le nom de largument :MonCmdlet Name "Explorer" Count 1 #devient MonCmdlet "Explorer" Count 1

La version 2 de PowerShell ne propose pas de crer des attributs comme en C#, mais dutiliser ceux dj disponibles pour les cmdlets C#. Lquipe de PowerShell a donc ajout quelques motscls spcifiques au contexte de dclaration dune fonction ou dun script.

Laurent Dardenne, libre de droits pour tous les usages non commerciaux.

Page 4 / 67

1.1

Principe dun attribut

Un attribut associe une ou plusieurs informations un lment du langage. Sous PowerShell seuls les paramtres dune fonction, dun script ou dun Scriptblock sont concerns par les attributs. Leur prsence indique au moteur PowerShell de modifier la gestion de ces paramtres, cest lui qui appliquera les nouveaux comportements prciss par les attributs que vous avez placs sur chacun dentre eux. Un attribut peut tre considr comme une mtadonne, c'est--dire une information sur une information. Voyons un exemple :Param ( [alias("CN")] $ComputerName )

On dclare un alias sur le paramtre $ComputerName. Il sera donc possible de le rfrencer, lors dun appel de cette fonction, par son nom dorigine ou par son nom dalias. Lattribut alias porte sur le paramtre $ComputerName. La dclaration de lattribut prcde celle du nom de paramtre. Sa syntaxe est la suivante : alias est le nom de lattribut, ("CN") est un argument renseignant une proprit de cet attribut. Celui-ci peut en dclarer plusieurs, dans ce cas on les sparera par des virgules. Le tout est dclar entre crochets [ ]. La syntaxe dun attribut est donc celle-ci :[NomAttribut(liste darguments)] ] Nom_de_paramtre_de_la_fonction

Ce qui permet les appels suivants :MaFonctionAvance -ComputerName "Server1" #ou MaFonctionAvance Cn "Server1"

On peut galement considrer un attribut comme tant un paramtrage, on paramtre du code, ici un paramtre, et pas un traitement. Ce paramtrage est destin au compilateur du code source PowerShell. 1.2 Les types dattribut de paramtre

Il existe trois types dattributs portant sur un paramtre : 1.2.1 Attribut Alias L'attribut Alias spcifie un autre nom pour le paramtre. Le nombre d'alias qui peuvent tre affects un paramtre est illimit. Attention les noms dalias suivants sont rservs : vb, db, ea, ev, ov, et ob.

Laurent Dardenne, libre de droits pour tous les usages non commerciaux.

Page 5 / 67

1.2.2 Attributs de validation de paramtres Ces attributs de validation de paramtres dfinissent la faon dont le runtime Windows PowerShell valide les arguments des fonctions avances. 1.2.3 Attribut Parameter L'attribut Parameter est utilis pour dclarer un paramtre de la fonction. Cet attribut comporte des arguments nomms utiliss pour dfinir les caractristiques du paramtre, par exemple pour savoir s'il est obligatoire ou optionnel. Il existe galement lattribut [CmdletBinding()] qui lui porte sur le comportement dune fonction ou dun script, nous laborderons par la suite. 1.3 Dclarer un attributFunction FcntAvance{ Param ( [Parameter(Position=0)] $NomParam, $Count) Write-host "`$NomParam=$NomParam `t `$Count=$Count reste=$args" }

On dclare un attribut au sein de la clause Param :

La dclaration suivante est autorise :Function FcntAvance( [Parameter(Position=0)] $NomParam, $Count){ Write-host "`$NomParam=$NomParam `t `$Count=$Count reste=$args" }

Cette fonction dclare le paramtre $NomParam en prcisant quil est en premire position. Testons notre fonction :FcntAvance "Deux" $NomParam=Deux $Count= reste= FcntAvance "Deux" 2

Le second appel provoque lerreur suivante :FcntAvance : Impossible de trouver un paramtre positionnel acceptant l'argument 2 .

Ceci est du au fait que la prsence dun paramtre positionnel nous contraint prciser le nom de ceux qui nont pas dindication de position, par exemple $count :FcntAvance "Deux" -count 2 $NomParam=Deux $Count=2 reste=

Laurent Dardenne, libre de droits pour tous les usages non commerciaux.

Page 6 / 67

Si on ajoute un paramtre anonyme , rcupr dhabitude dans la variable $args, cela provoque la mme erreur :FcntAvance "Deux" -count 2 3 FcntAvance : Impossible de trouver un paramtre positionnel acceptant l'argument 3 .

Modifions lattribut :Function FcntAvance{ Param ( [Parameter(Mandatory=$True)] $NomParam, $Count) Write-host "`$NomParam=$NomParam `t `$Count=$Count reste=$args"}

Cette fois on impose la prsence dun argument pour le paramtre $NomParam, testons cette modification :FcntAvance "Deux" 2 $NomParam=Deux $Count=2 reste= FcntAvance "Deux" 2 3 FcntAvance : Impossible de trouver un paramtre positionnel acceptant l'argument 3 . FcntAvance count 3 applet de commande FcntAvance la position 1 du pipeline de la commande Fournissez des valeurs pour les paramtres suivants : NomParam:

On constate que le premier appel ne ncessite plus de prciser le nom du second paramtre, le second appel provoque toujours une erreur, le troisime appel force PowerShell nous demander une valeur pour le premier paramtre, cest le comportement attendu.

Enfin pour lappel suivant PowerShell rorganise la liaison des paramtres :FcntAvance -count 4 deux $NomParam=deux $Count=4 reste=

On voit bien que la prsence ou labsence dattribut positionnel modifie cette liaison (Binding Parameters). Un autre point concernant la dclaration dattributs : on peut prciser plusieurs types dattribut sur chaque paramtre, mais lattribut Parameter doit tre unique :Function FcntAvance{ Param ( [Parameter(Mandatory=$True)] [Parameter(Position=0)] $NomParam, $Count) Write-host "`$NomParam=$NomParam `t `$Count=$Count" }

Laurent Dardenne, libre de droits pour tous les usages non commerciaux.

Page 7 / 67

FcntAvance deux 4 Le paramtre NomParam est dclar plusieurs fois dans le jeu de paramtres __AllParameterSets .

Le code prcdent provoque une erreur, car lattribut Parameter est prcis deux fois, on doit dclarer plusieurs arguments de la manire suivante :Function FcntAvance{ Param ( [Parameter(Mandatory=$True, Position=0)] $NomParam, $Count) Write-host "`$NomParam=$NomParam `t `$Count=$Count"}

2 Liaison de paramtresNous avons vu prcdemment que la prsence dattribut positionnel modifie la liaison des paramtres. La liaison est lopration daffectation dune valeur un paramtre, prcde dautres oprations, telle que la validation des rgles portes par les possibles attributs du paramtre. Il existe un autre attribut qui modifie cette liaison, lattribut [CmdletBinding()] qui doit tre imprativement coupl avec une instruction Param. Cet attribut prcise que notre fonction/script utilisera la mme liaison de paramtre quun cmdlet, c'est--dire que les paramtres inconnus et les arguments positionnels sans paramtre positionnel correspondant entranent l'chec de la liaison des paramtres en provoquant une exception. Cet attribut autorise dautres traitements que nous verrons par la suite. La prsence dans une fonction ou un script dun attribut Parameter ou CmdletBinding fait que PowerShell dclare une variable automatique nomme $PSCmdlet que nous aborderons plus avant dans ce tutoriel. Sachez quune fonction/script dclarant cet attribut n'utilise pas la variable $args. Cette variable est toujours prsente dans le provider variable:, mais elle rfrence celle dclare dans la porte parente. Le test suivant vous permettra de visualiser ce point :Function FcntTest{ Function FcntAvance{ #[CmdletBinding()] Param ( # [Parameter(ValueFromPipeline = $true)] $NomParam, $Count) Write-warning "Dans FcntAvance " if ($myinvocation.MyCommand.CmdletBinding) {Write-Host 'CmdletBinding dtect.' -fore Green} Write-host "`$NomParam=$NomParam `t `$Count=$Count" dir variable:args if (test-path Variable:PSCmdlet)

Laurent Dardenne, libre de droits pour tous les usages non commerciaux.

Page 8 / 67

{ Write-Host '$args inexistant localement' -fore Green Write-Host "`$PSCmdlet dclar dans $($pscmdlet.CommandRuntime)"` -fore Green } } Function FcntImbrique { [CmdletBinding()] Param ([Alias("Test")] $ParamTest) Write-warning "FcntImbrique : `$ParamTest=$ParamTest" if ($myinvocation.MyCommand.CmdletBinding) {Write-Host 'CmdletBinding dtect.' -fore Green} dir variable:args if (test-path Variable:PSCmdlet) {Write-Host 'Liaison modifie.' -fore Green} FcntAvance deux 10 # 7 "test" } Write-warning "Dans FcntTest" if ($myinvocation.MyCommand.CmdletBinding) {Write-Host 'CmdletBinding dtect.' -fore Green} dir variable:args FcntImbrique -Test un # 2 34 } FcntTest un 5 -4 test

Lajout ou la suppression des commentaires, sur tout ou partie des lignes prcdentes dclarant un attribut, modifiera le rsultat. Je vous laisse tester les diffrents cas. Il est possible de tracer le traitement de liaison de la manire suivante :Trace-Command -name ParameterBinding {FcntAvance "Deux" 2 3} pshost

Notez quil existe une variable automatique nomme $PSBoundParameters, pointant sur $MyInvocation.BoundParameters, contenant la liste des paramtres lis :Function Test-UnBoundArguments { param([String] $Name,[int]$Nombre=3,[switch] $Stop) $OutValue = $null if ($MyInvocation.BoundParameters.TryGetValue('Nombre', [ref]$OutValue)) { if ($OutValue -eq $null)

Laurent Dardenne, libre de droits pour tous les usages non commerciaux.

Page 9 / 67

{Write-Warning "Le paramtre Nombre prend la valeur `$null."} else {Write-Warning "Le paramtre Nombre est prcis et prend la valeur $OutValue."} } else { Write-Warning "Le paramtre Nombre n'est pas prcis, mais prend la valeur par dfaut." } #if ($PSBoundParameters.ContainsKey('Nombre')) # { write-host 'X Bound.' } "Nombre =$Nombre" }

Test-UnBoundArguments Test-UnBoundArguments -name "Test" Test-UnBoundArguments "Test" Test-UnBoundArguments "Test" 5 Test-UnBoundArguments "Test" $null Test-UnBoundArguments "Test" -nombre $null Test-UnBoundArguments "Test" -nombre

Sur le sujet vous pouvez galement consulter le schma suivant, Cmdlet Processing Lifecycle : http://msdn.microsoft.com/en-us/library/ms714429(VS.85).aspx Si, dans la dclaration dune fonction, vous ne prcisez pas la clause Param, vous devez prciser lattribut [CmdletBinding()] de la manire suivante :Function FcntAvance( [cmdletbinding()] [Parameter(Position=0)] $NomParam, $Count){ #[cmdletbinding()] -> erreur Write-host "`$NomParam=$NomParam `t `$Count=$Count reste=$args" }

Sinon la variable automatique nomme $PSCmdlet ne sera pas cre. 2.1 Convention de nommage de Paramtres

Comme pour le nommage des cmdlets, Microsoft recommande de suivre les prconisations portant sur le nommage des noms de paramtres. Lobjectif tant de faciliter leur usage auprs des administrateurs, cette convention facilitera la mmorisation et permettra galement de deviner rapidement quelles combinaisons utiliser lorsque les administrateurs rencontreront une nouvelle fonction/script avanc. Le dtail de cette convention : Cmdlet Parameter Name and Functionality Guidelines Laurent Dardenne, libre de droits pour tous les usages non commerciaux. Page 10 / 67

http://msdn.microsoft.com/en-us/library/dd878352(VS.85).aspx Strongly Encouraged Development Guidelines : http://msdn.microsoft.com/en-us/library/dd878270(VS.85).aspx Note : Les noms de paramtre SelectProperty et SelectObject sont rservs, leur usage gnrera une erreur :Le nom du paramtre SelectProperty est rserv pour une utilisation ultrieure. Le nom du paramtre SelectObject est rserv pour une utilisation ultrieure.

3 La gestion du pipelineLattribut Parameter facilite la liaison dune valeur dun paramtre donn avec un objet issu du pipeline. Pour cela on utilise largument ValueFromPipeline :Function FcntAvance{ Param ( [Parameter( Mandatory=$True, Position=0, ValueFromPipeline = $true)] $NomParam, $Count) Write-host "`$NomParam=$NomParam `t `$Count=$Count" }

On prcise ainsi quen cas dutilisation du pipeline lobjet transmis le sera dans la variable $NomParam. Lexemple suivant nous montre que la prsence de largument ValueFromPipeline ne met pas pour autant en place les blocs begin, process, end :1,2,3,4|FcntAvance -count 9 $NomParam=4 $Count=9

Il nous faut les prciser, au minimum le bloc process :Function FcntAvance{ Param ( [Parameter( Mandatory=$True, ValueFromPipeline = $true)] $NomParam, $Count) process { Write-host "`$NomParam=$NomParam `t `$Count=$Count" } } 1,2,3,4|FcntAvance count 9

Laurent Dardenne, libre de droits pour tous les usages non commerciaux.

Page 11 / 67

$NomParam=1 $NomParam=2 $NomParam=3 $NomParam=4

$Count=9 $Count=9 $Count=9 $Count=9

On constate que la liaison fonctionne et la valeur du paramtre $count est persistante pour tous les appels du bloc process. Pour plus de dtails sur le sujet, consultez le chapitre 3.2 du tutoriel L'usage du pipeline sous PowerShell : http://laurent-dardenne.developpez.com/articles/Windows/PowerShell/Pipelining/ Notez quun script .ps1 peut utiliser le pipeline en dclarant les blocs begin, process et end. 3.1 Diffrences entre la version 1 et la version 2

La gestion des objets issus du pipeline diffre lgrement, prenons lexemple suivant avec la version 1 de PowerShell :Function FcntAvanceV1{ Param ( $NomParam, $Count) process { Write-host "`$NomParam=$NomParam `t `$Count=$Count" } }

Lappel suivant fonctionne :FcntAvancev1 un 9 $NomParam=un $Count=9

Mais pas celui-ci, car la variable $NomParam nest pas lie :"un"|FcntAvancev1 -c 9 $NomParam= process { Write-host "`$NomParam=$_ `t `$Count=$Count" } $Count=9

On doit utiliser $_ reprsentant lobjet courant dans le pipeline :

Excutons de nouveau nos deux appels de test, vous remarquerez que cette fois-ci le rsultat est invers, le premier appel ne fonctionne pas, mais le second oui :FcntAvance un 9 $NomParam= $Count=9 "un"|FcntAvance -c 9 $NomParam=un $Count=9

Avec PowerShell version 1 on doit tester, dans une fonction utilisant le pipeline et dclarant les blocs process et end, si la liaison du paramtre se fait partir du pipeline ou pas. Sans prsence du pipeline cest le bloc end qui est excut :Function FcntAvanceV1{

Laurent Dardenne, libre de droits pour tous les usages non commerciaux.

Page 12 / 67

Param ( $NomParam, $Count) process { if ($_) {Write-host "`$NomParam=$_ `t `$Count=$Count"} } end { if ($NomParam) {Write-host "`$NomParam=$NomParam `t `$Count=$Count"} } }

Le code prcdent fonctionne correctement avec les deux exemples dappels. Il reste un souci qui est que lon peut utiliser le pipeline tout en prcisant le paramtre sur la ligne de commande :"un","Deux"|FcntAvanceV1 -Nom "Trois" -c 9 $NomParam=Un $Count=9 $NomParam=Deux $Count=9 $NomParam=Trois $Count=9

Dans ce cas, les 2 blocs sont excuts, pour viter cela on peut ajouter le test suivant :process { if ($NomParam -and $_) {throw "Impossible de coupler l'usage du pipeline avec le paramtre `$NomParam"}

Voyons cet aspect avec la version 2 de PowerShell :Function FcntAvanceV2{ Param ( [Parameter( ValueFromPipeline = $true)] $NomParam, $Count) process { Write-host "`$NomParam=$NomParam `t `$Count=$Count" } }

Testons nos deux appels de test :FcntAvanceV2 un 9 $NomParam= un $Count=9 "un"|FcntAvanceV2 -c 9

Laurent Dardenne, libre de droits pour tous les usages non commerciaux.

Page 13 / 67

$NomParam=un

$Count=9

Notez quavec la version 2, la liaison du nom de paramtre $NomParam fonctionne dans les deux cas. Pour terminer, testons notre cas derreur :"Un","Deux"|FcntAvanceV2 -Nom "Trois" -c 9 FcntAvance : L'objet d'entre ne peut tre li aucun paramtre de la commande, soit parce que cette commande n'accepte pas l'entre de pipeline, soit parce que l'entre et ses proprits ne correspondent aucun des paramtres qui acceptent l'entre de pipeline.

La version 2 le gre correctement, il dclenche une erreur non bloquante autant de fois quil y a dobjets reus. Le paramtre $NomParam tant dj li via la ligne de commande, le runtime ne trouve plus de paramtres lier avec un objet du pipeline et provoque une erreur. Si on ajoute notre fonction un bloc end, celui-ci sera excut, mais si on ne dclare aucun bloc le comportement diffre davec la premire la version, sans attribut (FcntAvanceV1 au dbut de ce chapitre) :Function FcntAvanceV2{ Param ( [Parameter(ValueFromPipeline = $true)] $NomParam, $Count) Write-host "`$NomParam=$NomParam `t `$Count=$Count" } FcntAvanceV2 un 9 $NomParam= un $Count=9 "un","Deux"|FcntAvanceV2 -c 9 $NomParam=Deux $Count=9

Notez que dans le second appel, la valeur $NomParam est gale au contenu du deuxime objet mis dans le pipeline, c'est--dire gal la valeur du dernier objet mis. Testons le cas derreur :"Un","Deux"|FcntAvanceV2 -Nom "Trois" -c 9 FcntAvance : L'objet d'entre ne peut tre li FcntAvance : L'objet d'entre ne peut tre li $NomParam=Trois $Count=9

Pour cet exemple, on saperoit que la prsence de lattribut Parameter, dclarant ValueFromPipeline, dclenche tout de mme, partir des donnes du pipeline, une itration sur la liaison, alors que le bloc process nexiste pas. Si on ne dclare que lattribut CmdletBinding le comportement est identique. Pour rcuprer lintgralit des donnes, il nous faut, comme sous PowerShell version 1, utiliser la variable $Input et modifier le type $NomParam en un tableau :Function FcntAvanceV2{ Param (

Laurent Dardenne, libre de droits pour tous les usages non commerciaux.

Page 14 / 67

[Parameter(ValueFromPipeline = $true)] [string[]] $NomParam, $Count) $NomParam=@($input) #Cast d'input en un tableau Write-host "`$NomParam=$NomParam `t `$Count=$Count" } "un","Deux"|FcntAvanceV2 -c 9 $NomParam=un Deux $Count=9

Lexemple suivant met en vidence un bug rfrenc, lusage dune fonction au sein dune sous expression $() provoque des itrations errones :function Get-Something { Write-Host 'Got something' 'Something' } function test { [CmdletBinding()] #

La prsence des caractres < >, en dehors dun commentaire multi lignes, sert ici de dlimiteur et ne fait pas partie la syntaxe : MaCommande $Variable|Select First 4 Etc. #>

Certains mots cls daide, tel que Example, peuvent tre prciss plusieurs fois, dautres sont usage unique. Consultez le fichier about_Comment_Based_Help.txt pour le dtail de cette convention et les rgles de formatage qui sy appliquent. Lusage de certains paramtres tels que Role, Component et Fonctionality, du cmdlet Get-Help ne fonctionne pas, en tout cas on ne sait pas trop comment les utiliser, part de cette manire :Get-Command |Foreach {(get-help $_.name).Component}

Donc, nhsitez pas consultez, le site MsConnect car cette fonctionnalit contient quelques bugs. De plus la prise en compte des retours la ligne ne semble possible quavec un format de fichier ASCII. 12.1 Construire un fichier daide localis au format MAML Une autre possibilit facilitant la localisation est dutiliser un fichier XML respectant le schma MAML (Multi-Agent Modeling Language) et contenant les mmes rubriques. Chaque fichier daide localis doit tre plac dans un rpertoire portant le mme nom que celui de la culture cible (fr-Fr) ou une culture neutre (fr). Le fichier daide par dfaut sera plac dans le rpertoire du script, il sera utilis sil nexiste pas de fichier localis pour la culture courante. Nous aurons donc, pour le script Test.ps1, larborescence suivante :

Laurent Dardenne, libre de droits pour tous les usages non commerciaux.

Page 64 / 67

La

C:\Scripts\Test.ps1 #une seule culture cible C:\Scripts\de-DE\Test-Help.xml #Culture allemande C:\Scripts\en-US\Test-Help.xml #Culture amricaine #plusieurs cultures cibles C:\Scripts\en\Test-Help.xml #Cultures anglaises C:\Scripts\fr\ Test-Help.xml #Cultures franaises C:\Scripts\Test-Help.xml #Culture invariante liste des noms de culture : http://msdn.microsoft.com/fr-fr/library/system.globalization.cultureinfo.aspx

Pour prciser le nom du fichier daide externe on utilise la balise de commentaire .ExternalHelp# .ExternalHelp C:\Scripts\Test-Help.xml # .ExternalHelp C:\Scripts\Script.ps1.xml

Les contraintes sont les suivantes : le dbut du nom de fichier daide doit correspondre au nom complet du module, de la fonction ou du script avec son extension, le chemin doit tre un nom de chemin complet, il ne peut pas rfrencer de variable, ni contenir despace (bug ?). Si cest le cas, utilisez un nom de fichier DOS 8.3. Sous Cmd.exe utilisez la commande Dir /x. Vous pouvez aussi utiliser le script ..\Help\GetShortPath.ps1 propos dans les sources. Il nest pas ncessaire de prciser le nom complet au format 8.3, seuls les rpertoires ou le nom de fichier comportant un espace peuvent ltre. Par convention, le nom du fichier XML peut tre postfix avec Help. La valeur de l'argument de la balise ExternalHelp (C:\MyScripts\MyHelpfile.xml) semble rsolue de la manire suivante : Le nom de fichier est spar du reste du chemin. Ce chemin (C:\MyScripts) devient le dossier de dpart pour la recherche. Le systme d'aide recherche un dossier portant le nom de la culture dinterface du systme d'exploitation (UI culture), telle que "en-US " ou "fr-FR ", dans les sous-dossiers du rpertoire de dmarrage. (C:\MyScripts\fr-FR). Si le fichier MAML spcifique n'est pas trouv, alors la logique de recherche de langue de secours est applique et les recherches du systme d'aide se font sur les dossiers portant un nom de langue alternative, tel que "en " ou "fr ". (C:\MyScripts\fr) Si le fichier MAML n'est toujours pas trouv, le systme d'aide le recherche alors dans le dossier de dpart (C:\MyScripts\MyHelpFile.xml) noter que le chemin daccs du fichier daide semble tre mis en cache par PowerShell, il faut donc, lors de la mise au point de laide, recharger le script ou recrer lobjet pour la prise en compte des modifications du fichier XML.

Laurent Dardenne, libre de droits pour tous les usages non commerciaux.

Page 65 / 67

Pour vous aider construire le squelette dun fichier XML MAML, vous pouvez utiliser les scripts suivants : New-MAML : http://www.poshcode.com/1338 New-XML : http://www.poshcode.com/1244 Lors de mes tests de localisation, jai constat que la modification de la culture du thread courant ninfluenait pas la recherche du fichier daide localis. Lusage de la balise ExternalHelp dans un script ne fonctionne pas correctement :Get-Help "$pwd\Script.ps1"

Seul le fichier XML prsent dans le mme rpertoire est pris en compte, de plus la prsence dun rpertoire ayant pour nom celui de la culture courante empchera le chargement de ce fichier daide. Voir aussi : How to Write Cmdlet Help : http://msdn.microsoft.com/en-us/library/aa965353(VS.85).aspx Creating the Cmdlet Help File : http://msdn.microsoft.com/en-us/library/bb525433(VS.85).aspx User Interface Language Management (Language Fallback in the Resource Loader) : http://msdn.microsoft.com/en-us/library/dd374098(VS.85).aspx La page suivante contient de nombreux lien sur le sujet : http://www.codeplex.com/wikipage?ProjectName=DocProject&title=Sandcastle%20Help Utilisation de la proprit InvariantCulture : http://msdn.microsoft.com/fr-fr/library/4c5zdc6a(VS.80).aspx Exemple de fichier daide dun module Powershell V2 : http://stackoverflow.com/questions/1432717/powershell-v2-external-maml-help Il est galement possible dutiliser une page web comme une aide online, consultez les posts suivants : http://www.leeholmes.com/blog/GetHelpNdashOnline.aspx http://chadwickmiller.spaces.live.com/Blog/cns!EA42395138308430!846.entry

13 LiensRecommandations de dveloppement de lquipe Microsoft PowerShell :http://blogs.msdn.com/powershell/archive/2009/04/16/increasing-visibility-of-cmdlet-design-guidelines.aspx

Cmdlet Development Guidelines : http://msdn.microsoft.com/en-us/library/ms714657(VS.85).aspx

Laurent Dardenne, libre de droits pour tous les usages non commerciaux.

Page 66 / 67

14 ConclusionIl reste srement des cas tudier, ce tutoriel vous donne de nombreux lments pour les raliser de votre ct. Ces nouvelles possibilits tirent le scripting vers le "haut" en simplifiant le dveloppement de traitements spcialiss. Lquipe de dveloppement de PowerShell nous dmontre quil est possible de faire simple, on se concentre sur le quoi et pas sur le comment. Toutefois, ces nouvelles possibilits ncessitent un temps dapprentissage consquent, mais le bnfice en vaut la chandelle et vous ne coderez plus de la mme manire. Jai pu constater maintes reprises que la documentation offline du produit est incomplte, voire errone. Pour aborder ces nouveauts laide fournie ne contient pas les dtails importants quant au fonctionnement, ni dexemples consquents. Je me suis souvent appuy sur Reflector pour trouver les informations manquantes, sans lui il maurait t difficile dapprofondir certains points. La comprhension du fonctionnement ne pose pas de problme particulier, mon avis la difficult dun tel codage rside dans la connaissance, ou plutt dans la mmorisation des diffrentes rgles qui peuvent sadditionner. Ce type de dveloppement peut vous amener aborder le SDK et les comportements sousjacents qui sont d'habitude transparents ou peu exploits. En mme temps rien ne vous oblige implmenter toutes ces nouveauts dans vos prochains scripts. De savoir quelles existent et quels sont leurs usages, vous permettra de les aborder progressivement. Certains bugs cits la fin du chapitre Diffrences entre la version 1 et la version 2 , limite mon avis lusage des fonctions avances. Par contre, je ne sais pas si Microsoft envisage de livrer prochainement un patch pour corriger ces quelques bugs mineurs. Enfin en cas de problme, nhsitez pas consulter MSConnect ou la documentation online US qui est mise jour suite aux remarques remontes sur MSConnect : http://technet.microsoft.com/en-us/library/bb978525.aspx Il reste, li au code, dautres nouveauts importantes telles que les modules, les vnements, En attendant, bon dev !

Laurent Dardenne, libre de droits pour tous les usages non commerciaux.

Page 67 / 67