1

This question is about passing switch parameters. Let's see the code. I have this PowerShell 3.0 function:

#test1.ps1
param(
    [switch] $param1 = $false
)

Write-Host "param1: $($param1.IsPresent)"
Write-Host

I have this main PowerShell function that invokes test.ps1 in four different ways:

#Test0.ps1
cls

$param1 = $True

# 1
.\test1.ps1 -param1

# 2
.\test1.ps1 -param1:$true

# 3
$potato = "-param1:`$$($param1)"
Write-Host "Parameter value: $potato" 
.\test1.ps1 $potato

# 4
$command = ".\test1.ps1 -param1:`$$($param1)"
Write-Host "Command: $command" 
iex $command

exit

Why is the 3rd way of doing it failing? I know I can do 4th way but I would love to understand why 3rd is failing.

Here is the output. As result all the parameters should be True but third one is False...

param1: True

param1: True

Parameter value: -param1:$True
param1: False

Command: .\test1.ps1 -param1:$True
param1: True

2 Answers 2

3

What happens is that:

  1. The parser looks at the provided argument: "-param1:$true"
  2. Fails to bind it to parameter param1, since the value you provided is a string, not a switch/bool
  3. No specific parameter type is required at position 0, argument is ignored

If you make param1 positional, you can see how PowerShell fails to bind it properly:

function test-parambinding {param([Parameter(Position=0)][switch]$param1);$param1.IsPresent}
test-parambinding "-param1:`$true"

You'll see a ParameterArgumentTransformationException thrown before anything else happens

Sign up to request clarification or add additional context in comments.

1 Comment

Well, yes, a non-empty string will be treated as $True when you cast it as a bool.
2

Mathias explains why your 3rd way of passing the parameter fails, but there is another way to pass parameters that lets you do roughly what you seem to be attempting here.

I've used a function here as it's a bit less to type when calling it, but your script file will work just the same:

PS C:\> function test1() {
param(
    [switch] $param1 = $false
)

Write-Host "param1: $($param1.IsPresent)"
Write-Host
}

PS C:\> $param1 = $True
PS C:\> $potato = @{'param1'=$param1}

PS C:\> $potato

Name                           Value                                                                                                  
----                           -----                                                                                                  
param1                         True                                                                                                   



PS C:\> test1 @potato
param1: True

So, instead of passing the argument and value as a single string, create a hash with the argument name as the key and the argument as the value. Then call the function or script using the @ splatting operator. (See help about_Splatting for more detail).

1 Comment

+1: This is not answering directly to the question (Why it fails) but gives a very interesting alternative

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.