5

I have a PS script, which get JSON in variable ant then saves it in file.

Unfortunately, it get value in one string, like this:

{   "persistentdataapi": "https://somevalue.azurewebsites.net/",   "collectioncountapi": "https://anothervalue.azurewebsites.net/",   "eventserviceapi": "https://thirdvalue.azurewebsites.net/",   "securityserviceapi": "https://fourthvalue.azurewebsites.net/" }

Is there any way, to process this value through some (preferably PS) JSON formatting, to get this one:

{
"persistentdataapi": "https://somevalue.azurewebsites.net/",
"collectioncountapi": "https://anothervalue.azurewebsites.net/",
"eventserviceapi": "https://thirdvalue.azurewebsites.net/",
"securityserviceapi": "https://fourthvalue.azurewebsites.net/",
}

Code to get value in Jenkins:

Import-Module "C:\Program Files\WindowsPowerShell\Modules\Octopus-Cmdlets\0.4.4\Octopus-Cmdlets.psd1"

connect-octoserver http://internal-Octopus.azure.com:8082 API-123456789012345678
$raw = (Get-OctoVariable var.Portal.Web DataAPIJson | Where-Object { $_.Environment -eq "QA" } )

$raw.Value | Out-File "$env:WORKSPACE\portal\var.Portal.Web\dataapi.json"
0

2 Answers 2

7

Powershell by default pretty-prints any JSON it produces.

So the correct way to do pretty-printing is to parse the JSON string into an object, and immediately convert it back to a JSON string.

$json = '{   "persistentdataapi": "https://somevalue.azurewebsites.net/",   "collectioncountapi": "https://anothervalue.azurewebsites.net/",   "eventserviceapi": "https://thirdvalue.azurewebsites.net/",   "securityserviceapi": "https://fourthvalue.azurewebsites.net/" }'

$json | ConvertFrom-Json | ConvertTo-Json

produces

{
    "persistentdataapi":  "https://somevalue.azurewebsites.net/",
    "collectioncountapi":  "https://anothervalue.azurewebsites.net/",
    "eventserviceapi":  "https://thirdvalue.azurewebsites.net/",
    "securityserviceapi":  "https://fourthvalue.azurewebsites.net/"
}

or in your case

$file = "$env:WORKSPACE\portal\var.Portal.Web\dataapi.json"
$raw.Value | ConvertFrom-Json | ConvertTo-Json | Out-File $file -Encoding UTF8

As a side-effect this also makes sure that the JSON in the file is valid, because otherwise ConvertFrom-Json will throw an error.

Please always explicitly specify UTF8 encoding when reading and writing JSON files.

$data = Get-Content $file -Encoding UTF8 | ConvertFrom-Json

$data | ConvertTo-Json | Set-Content $file -Encoding UTF8

The reason for that is

  • By widely-accepted convention, JSON files ought to be UTF8.
  • Unless specified otherwise, Get-Content and Set-Content will use the system's default encoding to read/write text files.
  • The system default is very seldom UTF-8, most of the time it will be a legacy single-byte encoding like Windows-1252.
  • This creates the risk of
    • mangling Unicode characters, which are legal in JSON, when reading a JSON file.
    • creating JSON files that are not UTF-8, making them hard to consume by others.

In fact, always specify an encoding explicitly when working with text files, not only in the case of JSON.

Sign up to request clarification or add additional context in comments.

Comments

2

PrettyifyJson.ps1

function PrettyifyJson ($FromFile, $ToFile) {
    Get-Content $FromFile |
      ConvertFrom-Json | 
      ConvertTo-Json -Depth 100 >> $ToFile
}

PrettyifyJson -FromFile foo-raw.json -ToFile foo-pretty.json

** sample-usage.ps1**

Get-ChildItem d*-raw.json | ForEach-Object {
    PrettyifyJson -FromFile $_ -ToFile ("$_".Replace('-raw.json', '.json'))
  }

1 Comment

While -Depth 100 is safe to use with DTOs ("property bags"), it can result in runaway serialization with arbitrary .NET types as input - see this answer. Also, unlike Tomalak's answer here, this answer doesn't address character-encoding pitfalls.

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.