Royce
Royce

Reputation: 585

Powershell variable expansion in single quoted string


I need to build a JSON variable that contains another JSON formatted content which should be formatted as a string. I'm putting the inner JSON into single quote so it wont get parsed along with the outer JSON. The inner JSON contains a variable that should be extended. Unfortunately, the single quotes prevent this.
Example:

$link = "http://www.google.de"
$event = @{
   var1 = "sys"
   var2 = "yadda"
   inner_json = '"System": {"link":"$link"}}'
}
$json = $event | ConvertTo-Json

The variable $inner_json must be embedded as a string. Is there any way to enforce the expansion of $link within the single quotes? Any other idea how to solve this problem? Any help is apprectiated.
edit: I would be expecting the inner_json like this:

{"var1":"sys", "var2":"yadda", "inner_json": "{\"System\": {\"link\":\"google.de\"}}"}

Upvotes: 3

Views: 2572

Answers (2)

mklement0
mklement0

Reputation: 440556

iRon's helpful answer contains the best solution for your use case.


To answer your question as suggested by its title, which is really a different use case:

You can use $ExecutionContext.InvokeCommand.ExpandString() to interpret verbatim strings as expandable ones on demand:

# A variable to reference in the template string below.
$link = 'http://example.org'

# A verbatim string that is to be interpreted as an expandable one later, on demand:
$template = '"System": {"link":"$link"}}'

# Expand the template, using the current values of the variables referenced:
$ExecutionContext.InvokeCommand.ExpandString($template)

The above yields a string with the following verbatim content; note how the value of $link was expanded:

"System": {"link":"http://example.org"}}

Upvotes: 1

iRon
iRon

Reputation: 23862

If you prepare the object (using a HashTable or PSCustomObject), variables (starting with a $, including $var1, $inner_json) will be automatically expanded anyway.
I think you want to do this:

$link = "http://www.google.de"
$event = @{
    var1 = 'sys'
    var2 = 'yadda'
    inner_json = @{
        System = @{
            link = $link
        }
    }
}
$event | ConvertTo-Json

{
  "inner_json": {
    "System": {
      "link": "http://www.google.de"
    }
  },
  "var2": "yadda",
  "var1": "sys"
}

Based on the added expectation:
*Note:
Double quotes are automatically escaped with a backslash (\) in json.
To escape a double quote in PowerShell, use the backtick: (`)

$link = "http://www.google.de"
$event = @{
    var1 = 'sys'
    var2 = 'yadda'
    inner_json = "{`"System`": {`"link`":`"$Link`"}}"
}
$event | ConvertTo-Json

{
  "inner_json": "{\"System\": {\"link\":\"http://www.google.de\"}}",
  "var2": "yadda",
  "var1": "sys"
}

But it is better to stay away from fabricating a Json string (including the inner Json string) and also create the inner Json from an object and literally embed that string into the outer Json:

$link = "http://www.google.de"
$event = @{
    var1 = 'sys'
    var2 = 'yadda'
    inner_json = @{System = @{link = $Link}} | ConvertTo-Json -Compress
}
$event | ConvertTo-Json

{
  "inner_json": "{\"System\":{\"link\":\"http://www.google.de\"}}",
  "var2": "yadda",
  "var1": "sys"
}

Upvotes: 5

Related Questions