web-dev-qa-db-fra.com

Powershell: Comment passer des variables pour changer de paramètres lors de l'appel de PowerShell sur la ligne de commande?

Normalement, si vous souhaitez reporter la spécification d'un paramètre de commutateur à une variable, vous pouvez passer une expression au paramètre de commutateur, comme indiqué 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 commutateurs. Cependant, lorsque 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:\test\test.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 lors du passage de -test:true, et -test:1. Pourquoi ça ne marche pas? 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?

Cela signifie-t-il que lors de l'appel de scripts PowerShell à partir d'un autre système (tel qu'un système de génération), il est nécessaire de construire des structures de contrôle de flux complexes pour déterminer s'il faut ou non inclure un commutateur dans la chaîne de commande, ou l'omettre? Cela semble fastidieux et sujet aux erreurs, ce qui m'amène à croire que ce n'est pas le cas.

30
bwerks

Ce comportement a été classé comme bug sur connect . Ceci est une solution de contournement:

powershell ./test.ps1 -source test.ps1 -dest test.copy.ps1 -test:$true
24
jon Z

Utilisez la propriété IsPresent du commutateur. 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.

13
Mike Shepard