Nested JSON powershell object

Hi,

I have a JSON file with data to build various components. One of the components is for a LoadBalancer with multiple rules.

The cmdlets i need to use reference the different rules. How do isolate the values of each rule?

$JSONFile = ConvertFrom-Json "$(get-content ".\ConfigurationData.json")"
$ConfigurationData = @{}
$JSONFile | get-member -MemberType NoteProperty | Where-Object{ -not [string]::IsNullOrEmpty($JSONFile."$($_.name)")} | ForEach-Object {$ConfigurationData.add($_.name,$JSONFile."$($_.name)")}

Example of some of the JSON file:

"LoadBalancers": {
            "Name": "####-LB-DMZ-IN",
            "Description": "LoadBalancer for the Public DMZ in network tier",
            "Location": "London",
            "PublicIPName": "####-LB-DMZ-IN-PUBLICIP",
            "AllocationMethod": "Dynamic",
            "ResourceGroupName": "####-RSG-PUB-DMZ-IN",
            "FEConfigName": "####-LB-FRONTEND",
            "BEConfigName": "####-LB-BACKEND",
            "Rules": [{
                        "Name": "NATRule1",
                        "RuleName": "####-DMZ-LB-NATRule-RDP",
                        "Protocol": "TCP",
                        "FEPort": "3389",
                        "BEPort": "3389",
                        "IdleTimeOut": "15"
                   },
                    {
                        "Name": "NatRule2",
                        "RuleName":"####-DMZ-LB-NATRule-TCPIP",
                        "Protocol": "TCP",
                        "FEPort": "3391",
                        "BEPort": "3392"
                   },
                    {
                        "Name": "Probe",
                        "RuleName": "HEALTHCHECK-HTTP80",
                        "Port": "80",
                        "ProbeInterval": "15",
                        "ProbeCount": "2"                        
                   },
                   {
                       "Name":"LBRule",
                       "RuleName": "####-DMZ-LB-RULE",
                       "Protocol": "TCP"
                    }]                     
    }

So the cmdlet will be something like this:

New-LBRule -Name $ConfigurationData.Loadbalancer.Rules.Name.Probe.RuleName

Sorry if this is a bit confusing as hard to explain what i want to do. I know i could just build individual elements for each rule in the JSON file, but i want to be a bit clever with how i build out the JSON and use the POWER of PowerShell build at the logic.

Any help, suggestions of betters ways would be cool.

Thanks

TommyQ

Hey Tommy,

Just a few things here:

Sorry if this is a bit confusing as hard to explain what i want to do.

We’ve all been there at one point or the other.

However, if you cannot explain / layout what it is you want, then that would indicate you are not sure what you want, Thus making it really difficult to provide any guidance.

Again, been there, done that as well, and had step back, to completly rethink stuff.

Of course, a computer can only do what that are told by the programmer. Unless you have AI code to deal with the gray areas and even that has to be programmed.

Yet, have you tried what you show here to see if it returns what you’d expect?

Hitting the easy stuff first.

The JSON fiile is not proper.
Copy and paste your JSON in this post to ‘jsonlint.com’ and click the ValidateJson button. It will error out.

    Results
    Error: Parse error on line 1:
    "LoadBalancers": {	"Name": "####-L
    ---------------^
    Expecting 'EOF', '}', ',', ']', got ':'

Even the JSON posted errors out in all JSON validators and fails for any JSON cmdlet

Note: The extra parens wrapping the line, are a thing I do to send results to the
screen, when needed, without using Write-* stuff, my lazyman’s debug. It has no impact on what’s being ran

    ($JSONFile = ConvertFrom-Json "$(Get-Content "d:\scripts\ConfigurationData.json")")

    
    ConvertFrom-Json : Invalid JSON primitive:  {             "Name": "####-LB-DMZ-IN",             
    "Description": "LoadBalancer for the Public DMZ in network tier",             "Location": 
    "London",             "PublicIPName": "####-LB-DMZ-IN-PUBLICIP", 
    ...

    ($JSONFile = Get-Content 'd:\scripts\ConfigurationData.json')

    $JSONFile | ConvertFrom-Json
    
    ConvertFrom-Json : Invalid JSON primitive:  {
                "Name": "####-LB-DMZ-IN",
                "Description": "LoadBalancer for the Public DMZ in network tier",
                ...

Hi Postanote,

Thanks for the reply. The JSON i provided was just a snippet of a much larger document. I have the script running correctly and using the JSON data as expected, but i wanted to add the nested rules for the loadbalancer within the Loadbalancer element.

Basically what i am trying to do is reference the nested values correctly.

{
	"loadbalancer": {
		"Name-of-LB": "LoadBalancer",
		"rules": [{
				"Name of rule": "Rule1",
				"Config": "Port80"
			},
			{
				"Name of rule": "Rule2",
				"Config": "Port443"

			}
		]
	}
}

Hey Tommy,
It’s simply an array that you can address like any standard array. See examples below.

$json = @"
{
	"loadbalancer": {
		"Name-of-LB": "LoadBalancer",
		"rules": [
            {
				"Name of rule": "Rule1",
				"Config": "Port80"
			},
			{
				"Name of rule": "Rule2",
				"Config": "Port443"
			},
            {
				"Name of rule": "Rule3",
				"Config": "Port803"
			},
			{
				"Name of rule": "Rule4",
				"Config": "Port4434"
			},
			{
				"Name of rule": "Rule5",
				"Config": "Port4435"
			}
		]
	}
}
"@ | ConvertFrom-Json

Write-Host "All Rules"
$json.loadbalancer.rules | Out-Host

Write-Host "First Rule"
$json.loadbalancer.rules[0] | Out-Host

Write-Host "Last Rule"
$json.loadbalancer.rules[-1] | Out-Host

Write-Host "Range of Rules"
$json.loadbalancer.rules[1..3] | Out-Host

Write-Host "Select Rule by Name"
$json.loadbalancer.rules[1..3] | Where-Object {$_.'Name of rule' -eq 'Rule3'} | Out-Host

Results:

All Rules

Name of rule Config  
------------ ------  
Rule1        Port80  
Rule2        Port443 
Rule3        Port803 
Rule4        Port4434
Rule5        Port4435


First Rule

Name of rule Config
------------ ------
Rule1        Port80


Last Rule

Name of rule Config  
------------ ------  
Rule5        Port4435


Range of Rules

Name of rule Config  
------------ ------  
Rule2        Port443 
Rule3        Port803 
Rule4        Port4434


Select Rule by Name

Name of rule Config 
------------ ------ 
Rule3        Port803