tester81
tester81

Reputation: 595

Powershell - create a json file

I have prepared Cloud Formation template, json format, below:

{
"AWSTemplateFormatVersion": "2010-09-09",
    "Resources": {
        "Baseline": {
            "Properties": {
            
                "ApprovalRules": {
                    "PatchRules": [
                        {
                            "PatchFilterGroup": {
                                "PatchFilters": [
                                    {
                                        "Values": [],
                                        "Key": ""
                                    },
                                    {
                                        "Values": [],
                                        "Key": ""
                                    },
                                    {
                                        "Values": [],
                                        "Key": ""
                                    }
                                ]
                            }

                        }
                    ]
                }
            }
        }
    }
}

I need to inject content to that json file, so prepared code. I need to inject two arrays: Values and Key

function ObjectBuilder {

    param (
    $Values,
    $Key
    )

    $counter = 0
    $objecttoinjectArray = @()
    foreach ($element1 in $Values) { 
            $objecttoinject = [pscustomobject][ordered] @{
                            Values = $element1
                            Key = $Key[$counter]
            }
            $objecttoinjectArray += $objecttoinject
            $counter++
        
    }
    return $objecttoinjectArray

}


$filename = "Matrix.json"
$content = Get-Content -Path .\$filename
$jsoncontent = $content | ConvertFrom-Json
$jsonbuild = $jsoncontent.Resources.Baseline.Properties
$Values = @("BMW, Audi", "Fiat, Ferrari, Porsche, Toyota", "*")
$Key = @("Standard","High","Premium")

$objecttoinjectArray = ObjectBuilder -Values $Values -Key $Key
$jsonbuild.ApprovalRules.PatchRules.PatchFilterGroup.PatchFilters = $objecttoinjectArray

$jsoncontent | 
ConvertTo-Json -Depth 15 | 
Set-Content .\tests.json

And as an output I can see incorrectly formatted json file, below:

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Resources": {
    "Baseline": {
      "Properties": {
        "ApprovalRules": {
          "PatchRules": [
            {
              "PatchFilterGroup": {
                "PatchFilters": [
                  {
                    "Values": "BMW, Audi",
                    "Key": "Standard"
                  },
                  {
                    "Values": "Fiat, Ferrari, Porsche, Toyota",
                    "Key": "High"
                  },
                  {
                    "Values": "*",
                    "Key": "Premium"
                  }
                ]
              }
            }
          ]
        }
      }
    }
  }
}

Proper structure should looks like presented below, that structure is not accepted by AWS cloudformation:

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Resources": {
    "Baseline": {
      "Properties": {
        "ApprovalRules": {
          "PatchRules": [
            {
              "PatchFilterGroup": {
                "PatchFilters": [
                  {
                    "Values": [
            "BMW", 
            "Audi"
            ],
                    "Key": "Standard"
                  },
                  {
                    "Values": [
            "Fiat", 
            "Ferrari", 
            "Porsche", 
            "Toyota"
            ],
                    "Key": "High"
                  },
                  {
                    "Values": [
            "*"
            ],
                    "Key": "Premium"
                  }
                ]
              }
            }
          ]
        }
      }
    }
  }
}

Upvotes: 1

Views: 326

Answers (1)

marsze
marsze

Reputation: 17035

That's because each item of your $Values is a string, not an array ("BMW, Audi" instead of "BMW", "Audi") and will be added to the JSON as such.

Depending on where you get those values from, there are several options:

If the strings come from a file, you would have to split them up:

$objecttoinject = [pscustomobject]@{
    # split up the string into an actual array of the values
    Values = $element1 -split ", "
    Key = $Key[$counter]
}

(btw, you can omit the [ordered] accelerator, because it is already implied by [pscustomobject])

If they are really literally defined inside your script, just change it too:

$Values = @(@("BMW", "Audi"), @("Fiat", "Ferrari", "Porsche", "Toyota"), @("*"))

Or even better, use a hashtable:

$hashtable = @{
    Standard = "BMW", "Audi"
    High = "Fiat", "Ferrari", "Porsche", "Toyota"
    Premium = "*"
}
$objecttoinjectArray = $hashtable.GetEnumerator() | foreach {
    [pscustomobject] @{
        Values = @($_.Value)
        Key = $_.Key
    }
}

Upvotes: 1

Related Questions