Skip to content

Executing powershell script with bool parameter doesnt work #4036

Closed

Description

@thepixelabs

Steps to reproduce

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

Environment data

Name Value


PSVersion 5.1.14393.1198
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.14393.1198
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1

Activity

  1. SteveL-MSFT commented on Jun 16, 2017

    @SteveL-MSFT
    Member

    Workaround:

    powershell -Command .\somescript.ps1 -someParameter $True
    

    Related #4024 where parameter parsing for -File and -Command differ

  2. thepixelabs commented on Jun 16, 2017

    @thepixelabs
    Author

    Steve Lee (@SteveL-MSFT) So is this a workaround as this is a known issue or is it working as expected?

  3. SteveL-MSFT commented on Jun 16, 2017

    @SteveL-MSFT
    Member

    @pixelicous expectation is that -Command and -File should behave similarly but that is not the case today and should be investigated

  4. thepixelabs commented on Jun 16, 2017

    @thepixelabs
    Author

    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

  5. added this to the milestone on Jun 20, 2017
  6. mklement0 commented on Jun 21, 2017

    @mklement0
    Contributor

    @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.

  7. thepixelabs commented on Jun 22, 2017

    @thepixelabs
    Author

    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"

  8. mklement0 commented on Jun 22, 2017

    @mklement0
    Contributor

    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.

  9. thepixelabs commented on Jun 25, 2017

    @thepixelabs
    Author

    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

  10. mklement0 commented on Jun 25, 2017

    @mklement0
    Contributor

    @pixelicous:

    No worries re delay.

    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:

    • -Foo:$True is the same as just -Foo

    • -Foo:$False is the same as not specifying -Foo.

  11. SteveL-MSFT commented on Jun 25, 2017

    @SteveL-MSFT
    Member

    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.

  12. mklement0 commented on Jun 25, 2017

    @mklement0
    Contributor

    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 no to signal negation: for instance, -noswitch would then take the place of -switch:$false.

  13. SteveL-MSFT commented on Jun 25, 2017

    @SteveL-MSFT
    Member

    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

  14. 1 remaining item

  15. BrucePay commented on Jun 28, 2017

    @BrucePay
    Collaborator

    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.

  16. mklement0 commented on Jun 28, 2017

    @mklement0
    Contributor

    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 $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)

  17. SteveL-MSFT commented on Jun 28, 2017

    @SteveL-MSFT
    Member

    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.

  18. added
    Committee-ReviewedPS-Committee has reviewed this and made a decision
    and removed
    Review - CommitteeThe PR/Issue needs a review from the PowerShell Committee
    on Jul 27, 2017
  19. SteveL-MSFT commented on Jul 27, 2017

    @SteveL-MSFT
    Member

    @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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions