My variable is the following in powershell:
$lcr=@{"tierToCool"=@{"daysAfterModificationGreaterThan"=1};"tierToArchive"=@{"daysAfterModificationGreaterThan"=2}}
Then when I run the template using an az cli command to pass the variable as an object into my arm template:
az deployment group create --subscription <hidden> --resource-group <hidden> --template-file <hidden> --parameters lcr=$lcr
I get the following error:
Failed to parse JSON: System.Collections.Hashtable
Error Detail: Expecting value: line 1 column 1 (char 0)
Is there something wrong with the way I'm passing the parameter into the template or the way I'm formatting it? Any help is greatly appreciated.
Building on the helpful comments:
az
, the Azure CLI, requires JSON as the --parameters
arguments, i.e., a JSON string, not a hashtable.
'System.Collections.Hashtable'
While --parameters (@{ lcr = $lcr } | ConvertTo-Json -Compress)
should be enough to send the JSON representation of your hashtable, the sad reality is that, as of PowerShell 7.1, you additionally need to \
-escape the embedded "
characters, due to a long-standing bug in argument-passing to external programs.
The most robust way to do this is (if there are no escaped "
in the string, -replace '"', '\"'
is enough):
--parameters ((@{ lcr = $lcr } | ConvertTo-Json -Compress) -replace '([\\]*)"', '$1$1\"')
If you have a JSON string literal or JSON string stored in variable, use the following to pass it to an external program (if the string is stored in a variable $var
, replace '{ "foo": "bar" }'
with $var
):
someProgram ... ('{ "foo": "bar" }' -replace '([\\]*)"', '$1$1\"')
See this answer for more information.
Therefore:
az deployment group create --subscription <hidden> --resource-group <hidden> --template-file <hidden> --parameters ((@{ lcr = $lcr } | ConvertTo-Json -Compress) -replace '([\\]*)"', '$1$1\"')
A general ConvertTo-Json
pitfall: You may need to use the -Depth
parameter for full to-JSON serialization, depending on how deeply nested your object graph is (not needed with your sample input) - see this post.