Passer une variable par référence en PowerShell
Comment passer une variable par référence en PowerShell ? Telle est la question qui m’a assailli alors que je venais de finir la réécrire une application C++ en PowerShell. Pour schématiser, le script contient des fonctions qui traitent des données issu d’un pipe, et un compteur s’incrémente dans le niveau le plus bas.
Function f{
param([parameter(ValueFromPipeline=$True)] $objects)
Process {
Foreach($object in $objects){
#conditions
manyRes $objet | f2
#utiliser compteur
}
}
}
Function f2{
param([parameter(ValueFromPipeline=$True)] $objects)
Process {
Foreach($object in $objects){
#conditions et compteur
}
}
}
AlotOfRes | f
</pre>
## Deux possibilités pour passer des variables par référence {#deux-possibilités-pour-passer-des-variables-par-référence}
* La référence classique avec **[ref]** qui fonctionne comme le **out** en C#.
* Utiliser les scopes de variable avec les commandlets ***-Variable**
L’exemple suivant illustre les 2 mécanismes.
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-powershell" data-lang="powershell">New-Variable -Name <span style="color:#e6db74">'varValueType'</span> -Scope <span style="color:#e6db74">'Script'</span> -Value <span style="color:#e6db74">'newValue'</span>
<span style="color:#75715e"># not working</span>
<span style="color:#66d9ef">function</span> ChangeFail(){
<span style="color:#e6db74">"MaFonction avant : $varValueType"</span>
$varValueType = <span style="color:#e6db74">'ChangeFail'</span>
<span style="color:#e6db74">"MaFonction apres : $varValueType"</span>
}
<span style="color:#75715e"># working by reference</span>
<span style="color:#75715e"># note : Reference Type do not need [ref]</span>
<span style="color:#66d9ef">function</span> ChangeRef{
<span style="color:#66d9ef">param</span>(
<span style="color:#66d9ef">[ref]</span>$varRef
)
<span style="color:#e6db74">"ChangeRef avant : </span>$($varRef.Value)<span style="color:#e6db74">"</span>
$varRef.Value= <span style="color:#e6db74">'ChangeRef'</span>
<span style="color:#e6db74">"ChangeRef apres : </span>$($varRef.Value)<span style="color:#e6db74">"</span>
}
<span style="color:#75715e">#working by Set-Variable</span>
<span style="color:#66d9ef">function</span> ChangeSetVariable(){
<span style="color:#e6db74">"ChangeSetVariable avant : $varValueType"</span>
Set-Variable -Name <span style="color:#e6db74">'varValueType'</span> -Value <span style="color:#e6db74">'ChangeSetVariable'</span> -Scope <span style="color:#e6db74">'Script'</span>
<span style="color:#e6db74">"ChangeSetVariable apres : $varValueType"</span>
}
<span style="color:#66d9ef">function</span> main(){
<span style="color:#e6db74">"Main: $varValueType"</span>
ChangeFail
<span style="color:#e6db74">"Main: $varValueType"</span>
ChangeRef -varRef (<span style="color:#66d9ef">[ref]</span>$varValueType)
<span style="color:#e6db74">"Main: $varValueType"</span>
<span style="color:#75715e">#$varValueType2.key</span>
ChangeSetVariable
<span style="color:#e6db74">"Main: $varValueType"</span>
}
main</pre>
<div class=<span style="color:#e6db74">"highlight"</span>><pre style=<span style="color:#e6db74">"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"</span>><code class=<span style="color:#e6db74">"language-bash"</span> data-lang=<span style="color:#e6db74">"bash"</span>>Main<span style="color:#960050;background-color:#1e0010">:</span> ChangeSetVariable
MaFonction avant <span style="color:#960050;background-color:#1e0010">:</span> ChangeSetVariable
MaFonction apres <span style="color:#960050;background-color:#1e0010">:</span> ChangeFail
Main<span style="color:#960050;background-color:#1e0010">:</span> ChangeSetVariable
ChangeRef avant <span style="color:#960050;background-color:#1e0010">:</span> ChangeSetVariable
ChangeRef apres <span style="color:#960050;background-color:#1e0010">:</span> ChangeRef
Main<span style="color:#960050;background-color:#1e0010">:</span> ChangeRef
ChangeSetVariable avant <span style="color:#960050;background-color:#1e0010">:</span> ChangeRef
ChangeSetVariable apres <span style="color:#960050;background-color:#1e0010">:</span> ChangeSetVariable
Main<span style="color:#960050;background-color:#1e0010">:</span> ChangeSetVariable&lt;/pre&gt;
<span style=<span style="color:#e6db74">"color:#75715e"</span>><span style="color:#75715e">## Les cmdlets associées aux variables et les scopes {#les-cmdlets-associées-aux-variables-et-les-scopes}</span></span>
Pour manipuler les variables, les commandlets ***-Variable** sont intuitives<span style="color:#960050;background-color:#1e0010">:</span>
* Clear-Variable <span style="color:#960050;background-color:#1e0010">:</span> supprimer la valeur d<span style="color:#960050;background-color:#1e0010">’</span>une variable
* Get-Variable <span style="color:#960050;background-color:#1e0010">:</span> obtenir une variable
* New-Variable <span style="color:#960050;background-color:#1e0010">:</span> créer une nouvelle variable
* Remove-Variable <span style="color:#960050;background-color:#1e0010">:</span> supprimer une variable et sa valeur
* Set-Variable<span style="color:#960050;background-color:#1e0010">:</span> définir une variable
Par contre, tester l<span style="color:#960050;background-color:#1e0010">’</span>existence d<span style="color:#960050;background-color:#1e0010">’</span>une variable est moins trivial. <span style=<span style="color:#e6db74">"color:#ae81ff"</span>>2</span> possibilités s<span style="color:#960050;background-color:#1e0010">’</span>offrent à vous <span style="color:#960050;background-color:#1e0010">:</span>
* Test-Path Variable<span style="color:#960050;background-color:#1e0010">:</span>&lt;scope&gt;<span style="color:#960050;background-color:#1e0010">:</span>&lt;variableName&gt;&lt;/variableName&gt;&lt;/scope&gt;
* Get-Variable en cachant les erreurs et vérifier le code de retour $?
&lt;div class<span style=<span style="color:#e6db74">"color:#f92672"</span>>=</span><span style=<span style="color:#e6db74">"color:#e6db74"</span>>&<span style="color:#75715e">#34;highlight&#34;</span>&gt;&lt;pre style<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;</span>&gt;&lt;code class<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;language-powershell&#34;</span> data-lang<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;powershell&#34;</span>&gt;Test-Path Variable&lt;span style<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;color:#960050;background-color:#1e0010&#34;</span>&gt;:&lt;/span&gt;script&lt;span style<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;color:#960050;background-color:#1e0010&#34;</span>&gt;:&lt;/span&gt;VarExist</span>
&amp;amp;gt; True
Get-Variable -Name VarExist -Scope &lt;span style<span style=<span style="color:#e6db74">"color:#f92672"</span>>=</span><span style=<span style="color:#e6db74">"color:#e6db74"</span>>&<span style="color:#75715e">#34;color:#e6db74&#34;</span>&gt;&amp;<span style="color:#75715e">#39;Script&amp;#39;&lt;/span&gt; -ErrorAction SilentlyContinue</span></span>
$?
&amp;amp;gt; True
Test-Path Variable&lt;span style<span style=<span style="color:#e6db74">"color:#f92672"</span>>=</span><span style=<span style="color:#e6db74">"color:#e6db74"</span>>&<span style="color:#75715e">#34;color:#960050;background-color:#1e0010&#34;</span>&gt;:&lt;/span&gt;script&lt;span style<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;color:#960050;background-color:#1e0010&#34;</span>&gt;:&lt;/span&gt;VarNotExist</span>
&amp;amp;gt; False
Get-Variable -Name VarNotExist -Scope &lt;span style<span style=<span style="color:#e6db74">"color:#f92672"</span>>=</span><span style=<span style="color:#e6db74">"color:#e6db74"</span>>&<span style="color:#75715e">#34;color:#e6db74&#34;</span>&gt;&amp;<span style="color:#75715e">#39;Script&amp;#39;&lt;/span&gt; -ErrorAction SilentlyContinue</span></span>
$?
&amp;amp;gt; False
&amp;lt;/pre&amp;gt;
J&lt;span style<span style=<span style="color:#e6db74">"color:#f92672"</span>>=</span><span style=<span style="color:#e6db74">"color:#e6db74"</span>>&<span style="color:#75715e">#34;color:#960050;background-color:#1e0010&#34;</span>&gt;’&lt;/span&gt;ai apprécié &lt;span style<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;color:#66d9ef&#34;</span>&gt;<span style="color:#f92672">[</span>ref<span style="color:#f92672">]</span>&lt;/span&gt; pour son côté rassurant en tant que développeur. Pourtant j&lt;span style<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;color:#960050;background-color:#1e0010&#34;</span>&gt;’&lt;/span&gt;ai choisi Set-Variable pour la propreté du code.</span>
Qu&lt;span style<span style=<span style="color:#e6db74">"color:#f92672"</span>>=</span><span style=<span style="color:#e6db74">"color:#e6db74"</span>>&<span style="color:#75715e">#34;color:#960050;background-color:#1e0010&#34;</span>&gt;’&lt;/span&gt;aurez vous choisi dans cette situation?</span>
**Références &lt;span style<span style=<span style="color:#e6db74">"color:#f92672"</span>>=</span><span style=<span style="color:#e6db74">"color:#e6db74"</span>>&<span style="color:#75715e">#34;color:#960050;background-color:#1e0010&#34;</span>&gt;:&lt;/span&gt;**</span>
&lt;span style<span style=<span style="color:#e6db74">"color:#f92672"</span>>=</span><span style=<span style="color:#e6db74">"color:#e6db74"</span>>&<span style="color:#75715e">#34;color:#66d9ef&#34;</span>&gt;<span style="color:#f92672">[</span>About_Scopes sur la technet<span style="color:#f92672">][</span>1<span style="color:#f92672">]</span>&lt;/span&gt;</span>
<span style=<span style="color:#e6db74">"color:#f92672"</span>>[</span>1<span style=<span style="color:#e6db74">"color:#f92672"</span>>]</span>&lt;span style<span style=<span style="color:#e6db74">"color:#f92672"</span>>=</span><span style=<span style="color:#e6db74">"color:#e6db74"</span>>&<span style="color:#75715e">#34;color:#960050;background-color:#1e0010&#34;</span>&gt;:&lt;/span&gt; https&lt;span style<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;color:#960050;background-color:#1e0010&#34;</span>&gt;:&lt;/span&gt;//technet.microsoft.com/en-us/library/hh847849.aspx&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</code></pre></div></span></code></pre></div>