Reputation: 38152
Suppose we have the following SwitchTest.ps
script
param(
[switch]$Flag = $false
)
echo "Flag: $Flag"
The following works as expected:
& ".\SwitchTest.ps1" -Flag
Flag: True
However this doesn't
& ".\SwitchTest.ps1" "-Flag"
Flag: False
Furthermore, if we modify SwitchTest.ps
to look like this:
param(
[switch]$Flag = $false,
[string]$Str = $null
)
echo "Flag: $Flag"
echo "Str: $Str"
We get this expected behavior:
& ".\SwitchTest.ps1" -Flag
Flag: True
Str:
And this unexpected one:
& ".\SwitchTest.ps1" "-Flag"
Flag: False
Str: -Flag
I tried -Flag true
, -Flag $true
, -Flag:$true
... no cigar. It looks like the switch param is "skipped" when quoted (i.e. when it's a proper string) - why? What do I do if I want to build "-Flag"
programmatically?
Upvotes: 2
Views: 5046
Reputation: 81
Your asking a very good question and have set up a very good test case. Let's leave flag without a parameter so it defaults to $Null. When you specify -Flag
by itself, PowerShell uses the switch paramater. But, PowerShell interprets "-Flag"
as a string and therefore tries to find a parameter that matches a string variable and passes that string (including the -
because it is in double quotes) to the parameter that matches [String]
type. Lastly, since you sent a string "-Flag"
to the string variable, the Flag
variable was left to its default value which was $Null
or $False
. Nice question.
Here's your code you can use to test this out.
#Put this in a script file, e.g. ParamTest.ps1
Flag: False
Str: -Flag
param(
[switch]$Flag,
[string]$Str = $null
)
Write-Output "Flag: $Flag"
Write-Output "Str: $Str"
Execute just as you did above:
& ".\SwitchTest.ps1" "-Flag"
But now that you see how PowerShell assigns passed in parameters, try the following to trigger the Flag
parameter as you intended were originally intending to do:
& .\ParamScript.ps1 "-Flag" -Flag
Upvotes: 4
Reputation: 46730
Forgive me if I am off-base, but if you want to have that flag conditionally set, drop the call operator and just use splatting.
PS M:\Scripts> $params = @{Flag=$true;Str="Bagels"}
PS M:\Scripts> .\switchTest.ps1 @params
Flag: True
Str: Bagels
Upvotes: 3
Reputation: 47862
The behavior you're seeing is exactly what I would expect.
If you want to build it programmatically, use Invoke-Expression
.
Upvotes: 1