1

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"
                  }
                ]
              }
            }
          ]
        }
      }
    }
  }
}
1
  • Pro tip: You should always use proper indentation in your functions, which will make your code a lot more readable and maintainable, for you and others. Commented Oct 14, 2020 at 9:16

1 Answer 1

1

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.