You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Executing powershell script with bool parameter doesnt work #4036
Run from CMD the following command
powershell -ExecutionPolicy Unrestricted -File .\somescript.ps1 -someParameter $True
In the script itself i have the following line
[Parameter(Mandatory=$true)] [bool] $installSQL
I tried playing with that line and the arguments in many ways, all fail.. i have to turn this into a string and make the string into a bool :\
Expected behavior
Script starting to work.. :)
Actual behavior
Error Message Cannot process
argument transformation on parameter 'installSQL'. Cannot convert value "System.String" to type "System.Boolean".
Boolean parameters accept only Boolean values and numbers, such as $True, $False, 1 or 0.
+ CategoryInfo : InvalidData: (:) [bootstrapImageScript.ps1], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,bootstrapImageScript.ps1
Steve Lee (@SteveL-MSFT) Ok thanks, hope this issue is solved soon, another thing that might be related.. I am writing a PS script that calls a function from a PSM1 file in the same directory.
When I test in PS ISE i remember to remove-module and extract/reimport the function..
The issue is that a boolean parameter from the main script doesn't get sent to the function correctly.
The main script receives a bool parameter when executed, i set it to $false, i pass that to the function as boolean but it always returns $true, no matter how i input ($false, $False, false, 0) or how i try to read that variable, such as:
if ($boolParam)
if ($boolParam -eq $false)
etc..
it always returns $true!!
The only thing that made it work is switching the bool parameter to switch parameter in the main script, the function the script is calling from module still with "BOOL", and it works now.. just didnt want to open another issue, this all seems to be related
@pixelicous: We'd need to know more about how you pass that Boolean and how the function is defined in order to diagnose the problem.
On a general note, whenever a nonempty string is cast to [bool], the result is $True - irrespective of the content of the string; e.g., [bool] 'False' yields $True.
However, with a parameter that is properly typed [bool], passing a string is prevented altogether.
Michael Klement (@mklement0) All is written in the first post. I wrote how i declare my parameter and how do i call that ps1 script. The string is not empty. i tried running:
"-myParam $true"
"-myParam $True"
"-myParam true"
"-myParam True"
"-myParam 1"
On all i received that same error, when i change that parameter to SWITCH, it goes away (when i specify "-myParam"
Your original problem is explained in #4024 (in short: with -File, whatever value you pass is interpreted as a string, whose conversion to [bool] then fails - a known problem).
In a follow-up comment you were complaining about a different issue that you feel is related ("pass that to the function as boolean but it always returns $true"), and that is the one I've requested clarification on.
Generally, using a [switch] parameter is preferable to a [bool] anyway, assuming it has a reasonable default value.
Michael Klement (@mklement0) hey, sorry im on a vacation and will only return back in around 2 weeks time, thus i cannot answer your exact question.
The reason why i do not use -myParam as a switch is because i'm passing that value between a few functions and tools from a control script. If i use this as a switch ill have to build the execution string with the argument or without, when i use $true or $false, the execution string is always the same with a parameter that changes, easier to read and understand..
Eventually.. i moved things around, i used the SWITCH parameter for the main control script, and BOOL for anything else, and it works now.. except for invoking powershell with -file, that still doesn't work.. but i still think it is related, if i wouldn't have used a SWITCH parameter in the main control but a BOOL one, it just doesnt get passed through.. i think it is looking whether that BOOL variable is filled with a value or not, thus sending back $true everytime although it should have sent back $false
As an aside (it doesn't solve the -File issue):
There actually is a way to use your command-building technique with [switch] parameters too, but the syntax is not often seen:
I wonder if we should support -switch [bool] syntax as I agree the current -switch:[bool] syntax is not obvious. Should be separate issue we anyone wants to pursue. I'll try to fix this and the -File arg issue next week.
The -switch:[bool] syntax is awkward (presumably because it was tacked on later), but necessary for disambiguation:
Consider & { param([switch] $Switch) $Switch } vs. & { param([switch] $Switch, [bool] $Bool) $Switch, $Bool } - how would you distinguish between the two with arguments -switch $true, for instance?
Note that some Unix utilities have solved this problem by adopting the convention of allowing any switch (option) to be prefixed with no to signal negation: for instance, -noswitch would then take the place of -switch:$false.
Michael Klement (@mklement0) positional parameters make it problematic for sure. Perhaps a non-breaking change would be to utilize the suggestion feature to suggest the colon syntax when it's not a valid set of parameters
Michael Klement (@mklement0) The -switch: [bool] syntax is deliberately awkward as there is really only one scenario for passing an actual parameter to a switch: commands calling commands (which you described nicely in an earlier comment.) If you expect the user to pass an actual parameter, then you should be using boolean. If your cmdlet requires the user to pass arguments to a switch parameter then your cmdlet should be redesigned.
Steve Lee (@SteveL-MSFT) No we can't support -switch [bool]. The current behavior is fundamental to how the parameter binder works.
-Command and -File are very different operations. -Command gathers all of the arguments into a string and then processes that string as a PowerShell script. On the other hand, -File points at a script and passes the remaining arguments to the process. The application receives these arguments through argv[] as strings. Process creation simply doesn't allow for the parent to pass anything but strings to the child process. The PowerShell runtime does do some interpretation on these strings (e.g. treating strings that start with '-' as parameters instead of arguments) but this is necessarily limited by the lack of type information.
The immediate issue here is the current fundamental inability to pass a Boolean value (whether as an actual [bool] parameter of with the -switch:<bool> syntax) when using -File, because such a value is invariably treated as a string (for the reasons you describe), and therefore rejected.
I think that needs to be addressed, such as by accepting string values $true and $false as well (just as it is possible to pass an integer as a string).
-File and -Command are indeed currently very different, but I think they shouldn't be - see #4024 (comment)
The current implementation makes the two different, but I agree with Michael Klement (@mklement0) that there doesn't seem to be a reason from a user experience why it should be different. Using the same code for -Command to collect the args and pass it as a string works for -File with .ps1 scripts, just need some additional code to handle scripts without .ps1 extension.
@PowerShell/powershell-committee the concern of supporting $true and $false is resolved with #4178, the concern regarding the difference between -file and -command in general is by design per #4024
Activity
SteveL-MSFT commentedon Jun 16, 2017
Workaround:
Related #4024 where parameter parsing for -File and -Command differ
thepixelabs commentedon Jun 16, 2017
Steve Lee (@SteveL-MSFT) So is this a workaround as this is a known issue or is it working as expected?
SteveL-MSFT commentedon Jun 16, 2017
@pixelicous expectation is that
-Commandand-Fileshould behave similarly but that is not the case today and should be investigatedthepixelabs commentedon Jun 16, 2017
Steve Lee (@SteveL-MSFT) Ok thanks, hope this issue is solved soon, another thing that might be related.. I am writing a PS script that calls a function from a PSM1 file in the same directory.
When I test in PS ISE i remember to remove-module and extract/reimport the function..
The issue is that a boolean parameter from the main script doesn't get sent to the function correctly.
The main script receives a bool parameter when executed, i set it to $false, i pass that to the function as boolean but it always returns $true, no matter how i input ($false, $False, false, 0) or how i try to read that variable, such as:
if ($boolParam)
if ($boolParam -eq $false)
etc..
it always returns $true!!
The only thing that made it work is switching the bool parameter to switch parameter in the main script, the function the script is calling from module still with "BOOL", and it works now.. just didnt want to open another issue, this all seems to be related
thanks in advance
mklement0 commentedon Jun 21, 2017
@pixelicous: We'd need to know more about how you pass that Boolean and how the function is defined in order to diagnose the problem.
On a general note, whenever a nonempty string is cast to
[bool], the result is$True- irrespective of the content of the string; e.g.,[bool] 'False'yields$True.However, with a parameter that is properly typed
[bool], passing a string is prevented altogether.thepixelabs commentedon Jun 22, 2017
Michael Klement (@mklement0) All is written in the first post. I wrote how i declare my parameter and how do i call that ps1 script. The string is not empty. i tried running:
"-myParam $true"
"-myParam $True"
"-myParam true"
"-myParam True"
"-myParam 1"
On all i received that same error, when i change that parameter to SWITCH, it goes away (when i specify "-myParam"
mklement0 commentedon Jun 22, 2017
Your original problem is explained in #4024 (in short: with
-File, whatever value you pass is interpreted as a string, whose conversion to[bool]then fails - a known problem).In a follow-up comment you were complaining about a different issue that you feel is related ("pass that to the function as boolean but it always returns $true"), and that is the one I've requested clarification on.
Generally, using a
[switch]parameter is preferable to a[bool]anyway, assuming it has a reasonable default value.thepixelabs commentedon Jun 25, 2017
Michael Klement (@mklement0) hey, sorry im on a vacation and will only return back in around 2 weeks time, thus i cannot answer your exact question.
The reason why i do not use -myParam as a switch is because i'm passing that value between a few functions and tools from a control script. If i use this as a switch ill have to build the execution string with the argument or without, when i use $true or $false, the execution string is always the same with a parameter that changes, easier to read and understand..
Eventually.. i moved things around, i used the SWITCH parameter for the main control script, and BOOL for anything else, and it works now.. except for invoking powershell with -file, that still doesn't work.. but i still think it is related, if i wouldn't have used a SWITCH parameter in the main control but a BOOL one, it just doesnt get passed through.. i think it is looking whether that BOOL variable is filled with a value or not, thus sending back $true everytime although it should have sent back $false
mklement0 commentedon Jun 25, 2017
@pixelicous:
No worries re delay.
As an aside (it doesn't solve the
-Fileissue):There actually is a way to use your command-building technique with
[switch]parameters too, but the syntax is not often seen:-Foo:$Trueis the same as just-Foo-Foo:$Falseis the same as not specifying-Foo.SteveL-MSFT commentedon Jun 25, 2017
I wonder if we should support
-switch [bool]syntax as I agree the current-switch:[bool]syntax is not obvious. Should be separate issue we anyone wants to pursue. I'll try to fix this and the-Filearg issue next week.mklement0 commentedon Jun 25, 2017
Steve Lee (@SteveL-MSFT):
The
-switch:[bool]syntax is awkward (presumably because it was tacked on later), but necessary for disambiguation:Consider
& { param([switch] $Switch) $Switch }vs.& { param([switch] $Switch, [bool] $Bool) $Switch, $Bool }- how would you distinguish between the two with arguments-switch $true, for instance?Note that some Unix utilities have solved this problem by adopting the convention of allowing any switch (option) to be prefixed with
noto signal negation: for instance,-noswitchwould then take the place of-switch:$false.SteveL-MSFT commentedon Jun 25, 2017
Michael Klement (@mklement0) positional parameters make it problematic for sure. Perhaps a non-breaking change would be to utilize the suggestion feature to suggest the colon syntax when it's not a valid set of parameters
1 remaining item
BrucePay commentedon Jun 28, 2017
Michael Klement (@mklement0) The
-switch: [bool]syntax is deliberately awkward as there is really only one scenario for passing an actual parameter to a switch: commands calling commands (which you described nicely in an earlier comment.) If you expect the user to pass an actual parameter, then you should be using boolean. If your cmdlet requires the user to pass arguments to a switch parameter then your cmdlet should be redesigned.Steve Lee (@SteveL-MSFT) No we can't support
-switch [bool]. The current behavior is fundamental to how the parameter binder works.-Command and -File are very different operations. -Command gathers all of the arguments into a string and then processes that string as a PowerShell script. On the other hand, -File points at a script and passes the remaining arguments to the process. The application receives these arguments through argv[] as strings. Process creation simply doesn't allow for the parent to pass anything but strings to the child process. The PowerShell runtime does do some interpretation on these strings (e.g. treating strings that start with '-' as parameters instead of arguments) but this is necessarily limited by the lack of type information.
mklement0 commentedon Jun 28, 2017
Bruce Payette (@BrucePay):
The immediate issue here is the current fundamental inability to pass a Boolean value (whether as an actual
[bool]parameter of with the-switch:<bool>syntax) when using-File, because such a value is invariably treated as a string (for the reasons you describe), and therefore rejected.I think that needs to be addressed, such as by accepting string values
$trueand$falseas well (just as it is possible to pass an integer as a string).-Fileand-Commandare indeed currently very different, but I think they shouldn't be - see #4024 (comment)SteveL-MSFT commentedon Jun 28, 2017
The current implementation makes the two different, but I agree with Michael Klement (@mklement0) that there doesn't seem to be a reason from a user experience why it should be different. Using the same code for -Command to collect the args and pass it as a string works for -File with .ps1 scripts, just need some additional code to handle scripts without .ps1 extension.
SteveL-MSFT commentedon Jul 27, 2017
@PowerShell/powershell-committee the concern of supporting
$trueand$falseis resolved with #4178, the concern regarding the difference between-fileand-commandin general isby designper #4024switch back to -Command instead of -File
workaround for known isssue with bool and powershell PowerShell/Power…