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"
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:
Modify the data, by replacing the Boolean values with their desired string representations:
[pscustomobject]
object graph returned by ConvertFrom-Json
and update its (leaf) properties.Preferably, only modify the display formatting of [bool]
values, without needing to modify the data, as zett42 suggests.
(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:
.ToString()
override is not honored when you cast an instance to [string]
(e.g., [string] $true
) or when you use it in an expandable string (e.g, "$true"
)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.
Invoke-WithTemporaryTypeData
function that scopes type-data modifications to a given piece of code (script block): see this Gist.Output (note the all-lowercase property values):
TrueValue FalseValue
--------- ----------
true false