You can use the following technique, taking advantage of being able to embed entire statements in your template via $(...) the subexpression operator; therefore, it should also be noted that you should generally only use this technique with template strings that you trust, given that arbitrary commands could be executed.
$var_1 = '"new" name'
$template = @'
{ "key1": "My name is $((Get-Variable var_1).Value -replace '"', '\"')" }
'@
$ExecutionContext.InvokeCommand.ExpandString($template)
The above yields:
{ "key1": "My name is \"new\" name" }
which is valid JSON.
Note the use of Get-Variable to access the value of variable ${var_1} indirectly, so that its embedded " chars. can be safely escaped as \", as required by JSON.
Since the above is a little cumbersome for multiple references, you could define an auxiliary function:
$var_1 = '"new" name'
# Aux. function that takes a variable name and returns its value with
# " chars. \-escaped.
function esc ($varName) { (Get-Variable $varName).Value -replace '"', '\"' }
# Now you can reference the variables using $(esc <var-name):
$template = @'
{ "key1": "My name is $(esc var_1)" }
'@
$ExecutionContext.InvokeCommand.ExpandString($template)
If you don't control the template string, more work is needed:
$var_1 = '"new" name'
# Aux. function that takes a variable name and returns its value with
# " chars. \-escaped.
function esc ($varName) { (Get-Variable $varName).Value -replace '"', '\"' }
# The original template with ${var}-style references.
$template = @'
{
"key1": "My name is ${var_1}",
}
'@
# Modify the template to replace ${var} references with $(esc var).
$modifiedTemplate = $template -replace '\$\{(\w+)\}', '$$(esc $1)'
# Now expand the modified template.
$ExecutionContext.InvokeCommand.ExpandString($modifiedTemplate)
Note that the template transformation assumes: Tip of the hat to briantist for his input.
that there are no escaped variable references to be treated as literals in the input template (e.g., `${var}).
that all variable references have the form ${varName}, where varName is assumed to be composed of letters, digits, and underscores only (matching one or more \w instances).
A more robust solution that covers all edge cases may require using PowerShell's parsing API, which requires significantly more effort, however.