Powershell: Comment passer des variables pour changer les paramètres en invoquant powershell à la ligne de commande?

Normalement, si vous voulez reporter la spécification d'un paramètre switch à une variable, vous pouvez passer une expression au paramètre switch, comme vu avec le paramètre WhatIf.

test.ps1

param ( [string] $source, [string] $dest, [switch] $test )
Copy-Item -Path $source -Destination $dest -WhatIf:$test

cela vous permet une grande flexibilité lorsque vous travaillez avec des interrupteurs. Cependant, quand vous appelez powershell avec cmd.exe ou quelque chose, vous vous retrouvez avec quelque chose comme ceci:

D:test>powershell -file test.ps1 -source test.ps1 -dest test.copy.ps1 -test:$true

D:testtest.ps1 : Cannot process argument transformation on
parameter 'test'. Cannot convert value "System.String" to type "System.Manageme
nt.Automation.SwitchParameter", parameters of this type only accept booleans or
 numbers, use $true, $false, 1 or 0 instead.
At line:0 char:1
+  <<<<
    + CategoryInfo          : InvalidData: (:) [test.ps1], ParentContainsError
   RecordException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,test.ps1

cependant, le même résultat apparaît en passant -test:true et -test:1. Pourquoi ne pas ce travail? Le système de conversion de type de Powershell ne devrait-il pas reconnaître automatiquement ces chaînes comme étant convertibles en bool ou switch, et les convertir?

Est-ce que cela signifie que lorsque vous appelez des scripts powershell d'un autre système (tel qu'un système de construction) il est nécessaire de construire des structures complexes de contrôle du flux pour déterminer s'il faut inclure ou non un commutateur dans la chaîne de commande, ou l'omettre? Cela semble fastidieux et source d'erreur, ce qui m'amène à croire que ce n'est pas le cas.

27
demandé sur bwerks 2012-07-06 22:24:43

2 réponses

ce comportement a été classé comme un bug sur se connecter. C'est une solution de contournement:

powershell ./test.ps1 -source test.ps1 -dest test.copy.ps1 -test:$true
22
répondu jon Z 2012-07-08 18:21:50

Utilisez la propriété IsPresent de l'interrupteur. Exemple:

function test-switch{
param([switch]$test)
  function inner{
    param([switch]$inner_test)
    write-host $inner_test
  }
  inner -inner_test:$test.IsPresent
}
test-switch -test:$true
test-switch -test
test-switch -test:$false

True
True
False

BTW, j'ai utilisé des fonctions plutôt qu'un script donc ce serait plus facile à tester.

12
répondu Mike Shepard 2012-07-06 20:12:03