windowspowershellpowershell-7.0powershell-7.2

How to Stop powershell form Converting the variable assigment of a boolean to Uppercase letter


I am trying to format a json and do dynamic variable assignment but once the boolean value is assigned powershell is changing the casetype for the first letter to uppercase. I still want to maintain the case type for my input values both lowercase and uppercase as it is in my json file.

Any help?

      {

          "input": true,
          "variable": "Relative path",
       }

  $path= "L:\test\parameter.json"
  $json = Get-Content $path | ConvertFrom-Json
  foreach ($data in $json.PSObject.Properties) { New-Variable -name $($data.name) -value $($data.value) -Force}
  
  echo $input
  True   ->>> I want it to be "true" and the value of variable to still be "Relative Path"

Solution

  • Generally, you mustn't use $input as a custom variable, because it is an automatic variable managed by PowerShell.

    Leaving that aside, ConvertFrom-Json converts a true JSON value - a Boolean - into the equivalent .NET Boolean (System.Boolean, represented as [bool] in PowerShell). The representation of this value in PowerShell is $true.

    Printing this value to the console (host) effectively calls its .ToString() method in order to obtain a string representation, and that string representation happens to start with an uppercase letter:

    PS> $true
    True 
    

    If you need an all-lowercase representation, call .ToString().ToLower(), or, for brevity, use an expandable string and call .ToLower() on it:

    PS> "$true".ToLower() # In this case, the same as $true.ToString().ToLower()
    true
    

    If you want to apply the all-lowercase representation automatically to all Booleans, you have two options:


    (Temporarily) overriding the .ToString() method of type [bool]:

    Update-TypeData can be used to override the members of arbitrary .NET types, but there is a limitation due to a bug - reported in GitHub issue #14561 - present up to at least PowerShell 7.2.2:

    However, with implicit stringification of Booleans, as happens during for-display formatting, it does work:

    # Override the .ToString() method of [bool] (System.Boolean) instances:
    # Save preexisting type data, if any.
    $prevTypeData = Get-TypeData -TypeName System.Boolean
    # Add a ScriptMethod member named 'ToString' that outputs an
    # all-lowercase representation of the instance at hand. ('true' or 'false')
    Update-TypeData -TypeName System.Boolean `
                    -MemberType ScriptMethod -MemberName ToString `
                    -Value { if ($this) { 'true' } else { 'false' } } `
                    -Force
    
    # Output a sample custom object with two Boolean properties.
    [pscustomobject] @{ 
      TrueValue = $true
      FalseValue = $false
    }
    
    # Restore the original behavior:
    # Note: In production code, it's best to put this in the `finally`
    #       block of try / catch / finally statement.
    # Remove the override again...
    Remove-TypeData -TypeName System.Boolean
    # ... and restore the previous data, if any.
    if ($prevTypeData) { Update-TypeData -TypeData $prevTypeData }
    

    Note: You cannot scope Update-TypeData calls, which invariably take effect session-globally, so it's best to remove the override again with Remove-TypeData and restore any preexisting type data, if any, as shown above.

    Output (note the all-lowercase property values):

    TrueValue FalseValue
    --------- ----------
         true      false