Nested JSON powershell object

This topic contains 3 replies, has 3 voices, and was last updated by  Curtis Smith 2 months, 2 weeks ago.

  • Author
    Posts
  • #95128

    TommyQuality
    Participant

    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

  • #95145

    postanote
    Participant

    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",
                    ...
    
    
    • #95194

      TommyQuality
      Participant

      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"
      
      			}
      		]
      	}
      }
      
  • #95208

    Curtis Smith
    Participant

    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

You must be logged in to reply to this topic.