How to pass a switch parameter to another PowerShell script?

PowershellParameter Passing

Powershell Problem Overview


I have two PowerShell scripts, which have switch parameters:

compile-tool1.ps1:

[CmdletBinding()]
param(
  [switch]$VHDL2008
)

Write-Host "VHDL-2008 is enabled: $VHDL2008"

compile.ps1:

[CmdletBinding()]
param(
  [switch]$VHDL2008
)

if (-not $VHDL2008)
{ compile-tool1.ps1            }
else
{ compile-tool1.ps1 -VHDL2008  }

How can I pass a switch parameter to another PowerShell script, without writing big if..then..else or case statements?

I don't want to convert the parameter $VHDL2008 of compile-tool1.ps1 to type bool, because, both scripts are front-end scripts (used by users). The latter one is a high-level wrapper for multiple compile-tool*.ps1 scripts.

Powershell Solutions


Solution 1 - Powershell

You can specify $true or $false on a switch using the colon-syntax:

compile-tool1.ps1 -VHDL2008:$true
compile-tool1.ps1 -VHDL2008:$false

So just pass the actual value:

compile-tool1.ps1 -VHDL2008:$VHDL2008

Solution 2 - Powershell

Try

compile-tool1.ps1 -VHDL2008:$VHDL2008.IsPresent 

Solution 3 - Powershell

Assuming you were iterating on development, it is highly likely that at some point you are going to add other switches and parameters to your main script that are going to be passed down to the next called script. Using the previous responses, you would have to go find each call and rewrite the line each time you add a parameter. In such case, you can avoid the overhead by doing the following,

.\compile-tool1.ps1 $($PSBoundParameters.GetEnumerator() | ForEach-Object {"-$($_.Key) $($_.Value)"})

The automatic variable $PSBoundParameters is a hashtable containing the parameters explicitly passed to the script.

Please note that script.ps1 -SomeSwitch is equivalent to script.ps1 -SomeSwitch $true and script.ps1 is equivalent to script.ps1 -SomeSwitch $false. Hence, including the switch set to false is equivalent to not including it.

Solution 4 - Powershell

According to a power shell team's blog (link below,) since V2 there is a technique called splatting. Basically, you use the automatic variable @PsBoundParameters to forward all the parameters. Details about splatting and the difference between @ and $ are explained in the Microsoft Docs article (link below.)

Example:

parent.ps1

#Begin of parent.ps1     
param(
    [Switch] $MySwitch
    )

 Import-Module .\child.psm1     

Call-Child @psBoundParameters
#End of parent.ps1

child.psm1

# Begin of child.psm1
function Call-Child {
    param(
        [switch] $MySwitch
    )

    if ($MySwitch){
        Write-Output "`$MySwitch was specified"
    } else {
        Write-Output "`$MySwitch is missing"
    }
}
#End of child.psm1

Now we can call the parent script with or without the switch

PS V:\sof\splatting> .\parent.ps1 
$MySwitch is missing

PS V:\sof\splatting> .\parent.ps1 -MySwitch
$MySwitch was specified

PS V:\sof\splatting> 

Update

In my original answer, I sourced the children instead of importing it as a module. It appears sourcing another script into the original just makes the parent's variables visible to all children so this will also work:

# Begin of child.ps1
function Call-Child {
    if ($MySwitch){
        Write-Output "`$MySwitch was specified"
    } else {
        Write-Output "`$MySwitch is missing"
    }

}
#End of child.ps1

with

#Begin of parent.ps1     
param(
    [Switch] $MySwitch
    )

. .\child.ps1    

 Call-Child # Not even specifying @psBoundParameters   
#End of parent.ps1

Maybe, this is not the best way to make a program, nevertheless, this is the way it works.

About Splatting(Microsoft Docs)

How and Why to Use Splatting (passing [switch] parameters)

Solution 5 - Powershell

Another solution. If you declare your parameter with a default value of $false:

[switch] $VHDL2008 = $false

Then the following (the -VHDL2008 option with no value) will set $VHDL2008 to $true:

compile-tool1.ps1 -VHDL2008

If instead you omit the -VHDL2008 option, then this forces $VHDL2008 to use the default $false value:

compile-tool1.ps1

These examples are useful when calling a Powershell script from a bat script, as it is tricky to pass a $true/$false bool from bat to Powershell, because the bat will try to convert the bool to a string, resulting in the error:

Cannot process argument transformation on parameter 'VHDL2008'. 
Cannot convert value "System.String" to type "System.Management.Automation.SwitchParameter". 
Boolean parameters accept only Boolean values and numbers, such as $True, $False, 1 or 0.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPaebbelsView Question on Stackoverflow
Solution 1 - PowershellMartin BrandlView Answer on Stackoverflow
Solution 2 - PowershellwhateverView Answer on Stackoverflow
Solution 3 - PowershelldacabdiView Answer on Stackoverflow
Solution 4 - PowershellKraussView Answer on Stackoverflow
Solution 5 - PowershellPolyfunView Answer on Stackoverflow