3


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\"}}"}
3
  • 1
    Can you post the json you're expecting from your example $event | ConvertTo-Json? You can possibly solve this by using nested hashtables, but seeing your desired json would make sure... Commented Jan 20, 2020 at 8:36
  • $inner_json = """System"": {""link"":""$($link)""}}" Commented Jan 20, 2020 at 8:56
  • I would be expecting: {"var1":"sys", "var2":"yadda", "inner_json": "{\"System\": {\"link\":\"google.de\"}}"} Commented Jan 20, 2020 at 10:43

2 Answers 2

5

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"
}
Sign up to request clarification or add additional context in comments.

3 Comments

Makes sense, but the inner json would be parsed. see my comment above how the outer json should look like
note that if order of properties is important you can create an OrderedDictionary instead of a hashtable with $event = [ordered] @{ ... }
Thanks a lot! the convertto-json on the inner_json did the trick!
1

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"}}

1 Comment

This is a more generic usecase and also works as a solution for my issue. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.