powershellparameter-passingcommand-line-interface

How to specify switch parameter when calling a script from batch file


I have a script foo.ps1 and a batch file foo.cmd used to launch the script by double clicking the cmd file in file explorer.

The script accepts a switch parameter, but I don't know how to provide this kind of parameter. Simple parameters are ok.

Foo.ps1:

param(
    [Parameter()]
    [Switch]$MySwitch,
    [Parameter()]
    [string]$Name
)

Write-Host "`$MySwitch : $MySwitch, `$Name : $name"

Foo.cmd:

Powershell -noprofile -NonInteractive -file "%~dp0\foo.ps1" -Name "abc"    

If I call the script with only "Name", it works. But If I specify MySwitch, it stops to work:

Foo2.cmd:

Powershell -noprofile -NonInteractive -File "%~dp0\foo.ps1" -Name "abc" -MySwitch:$false

The error is:

C:\temp\foo.ps1 : Impossible de traiter la transformation d'argument sur le paramètre «MySwitch». Impossible de convertir la valeur «System.String» en type « System.Management.Automation.SwitchParameter». Les paramètres booléens acceptent seulement des valeurs booléennes et des nombres, tels que $True, $False, 1 ou 0.
    + CategoryInfo          : InvalidData : (:) [foo.ps1], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,foo.ps1

Solution

  • In Windows PowerShell, there is no way to pass Boolean values when powershell.exe's
    -File parameter is used
    - this has has since been corrected in PowerShell (Core) 7, whose CLI is pwsh.exe[1].

    Use the workaround that JosefZ recommends:

    Use of -Command (-c) instead of -File makes PowerShell treat the arguments as PowerShell source code rather than literal arguments, in which case $false is properly recognized (other CLI parameters omitted for brevity).

    powershell -c "& \"%~dp0\foo.ps1\" -Name 'abc' -MySwitch:$false"  
    

    Note:


    On a conceptual note:


    [1] PowerShell (Core) 7 supports the following Boolean values when -File is used: $true, $false, true, false (and also $null, but its interpretation differs situationally: scripts (including with -File) and functions interpret it as $false, whereas cmdlets interpret it as $true(!)).
    Note that with -Command - and therefore in all PowerShell code - true and false do not work, but 0 and 1 do.
    Unfortunately, if you pass an unsupported value, you get the same error message in all scenarios, which in the -File scenario misleadingly suggests that 0 and 1 work too.