skip to Main Content

I’m using az vm list-skus -l australiasoutheast | convertfrom-json to populate a variable (lets call it $skus) so I can use it in a PS script. When $skus is populated, it’s contents look like:

apiVersions  :
capabilities : {@{name=MaxResourceVolumeMB; value=256000}, @{name=OSVhdSizeMB; value=1047552}, @{name=vCPUs; value=8}, @{name=MemoryPreservingMaintenanceSupported; value=False}…}
capacity     :
costs        :
family       : standardMSFamily
kind         :
locationInfo : {@{location=australiasoutheast; zoneDetails=System.Object[]; zones=System.Object[]}}
locations    : {australiasoutheast}
name         : Standard_M8-4ms
resourceType : virtualMachines
restrictions : {}
size         : M8-4ms
tier         : Standard

The capabilities and locatioinfo objects in the variable look like hashtables.

I can do $skus | select name, capabilities which outputs:

name                   capabilities
----                   ------------
Aligned                {@{name=MaximumPlatformFaultDomainCount; value=2}}
Classic                {@{name=MaximumPlatformFaultDomainCount; value=3}}
Premium_LRS            {@{name=MaxSizeGiB; value=4}, @{name=MinSizeGiB; value=0}, @{name=MaxIOps; value=120}, @{name=MinIOps; value=120}…}
Premium_LRS            {@{name=MaxSizeGiB; value=128}, @{name=MinSizeGiB; value=64}, @{name=MaxIOps; value=500}, @{name=MinIOps; value=500}…}
Premium_LRS            {@{name=MaxSizeGiB; value=256}, @{name=MinSizeGiB; value=128}, @{name=MaxIOps; value=1100}, @{name=MinIOps; value=1100}…}

How can I get to and extract the data I need from those hashtables?

I tried the usual select-object to try and get to it, but I can only get as far as the capabilities object, but I cannot reference anything inside that.

2

Answers


  1. How can I get to and extract the data I need from those hashtables?

    To retrieve all capabilities from a hash table, use Select-Object to print the specific value from the capabilities parameter.

    Here is the PowerShell script to reference the value from capabilities parameter.

    $skus = az vm list-skus -l australiasoutheast | convertfrom-json
    $skus | Where-Object { $_.Capabilities -ne $null } | ForEach-Object {
        $matchingCapability = $_.Capabilities | Where-Object { $_.Name -eq "OSVhdSizeMB" -and $_.Value -eq 1047552 }
        if ($matchingCapability -ne $null) {
            $_ | Select-Object Name, @{ Name = "Capabilities"; Expression = { $matchingCapability } }
        }
    }
    

    Output:

    enter image description here

    To display all values within capabilities, you can utilize the following cmdlet to print only name and values.

      $skus | Select-Object Name, @{ Name = "Capabilities"; Expression = { $_.Capabilities | ForEach-Object { $_.Name + ": " + $_.Value } } }
    

    Output:

    enter image description here

    Login or Signup to reply.
  2. Without knowing the exact structure and data of the object-graph, it is difficult to give you a specific answer (see also how to ask and providing a mvce) but based on this example (note that Value is actually the top node) and this Object-Graph tools set, I can give you a general view and answer:

    {
      "value": [
    {
      "resourceType": "virtualMachines",
      "locations": [
        "westus"
      ],
      "capabilities": [
        {
          "name": "MaxResourceVolumeMB",
          "value": "20480"
        },
        {
          "name": "OSVhdSizeMB",
          "value": "1047552"
        },
        {
          "name": "vCPUs",
          "value": "1"
        },
        {
          "name": "HyperVGenerations",
          "value": "V1"
        },
        {
          "name": "MemoryGB",
          "value": "0.75"
        },
        {
          "name": "MaxDataDiskCount",
          "value": "1"
        },
        {
          "name": "LowPriorityCapable",
          "value": "False"
        },
        {
          "name": "PremiumIO",
          "value": "False"
        },
        {
          "name": "vCPUsAvailable",
          "value": "1"
        },
        {
          "name": "ACUs",
          "value": "50"
        },
        {
          "name": "vCPUsPerCore",
          "value": "1"
        },
        {
          "name": "EphemeralOSDiskSupported",
          "value": "False"
        },
        {
          "name": "AcceleratedNetworkingEnabled",
          "value": "False"
        },
        {
          "name": "RdmaEnabled",
          "value": "False"
        },
        {
          "name": "MaxNetworkInterfaces",
          "value": "2"
        }
      ],
      "locationInfo": [
        {
          "location": "westus",
          "zones": [
            "2",
            "1"
          ],
          "zoneDetails": [
            {
              "name": [
                "2"
              ],
              "capabilities": [
                {
                  "name": "UltraSSDAvailable",
                  "value": "True"
                }
              ]
            }
          ]
        }
      ],
      "name": "Standard_A0",
      "tier": "Standard",
      "size": "A0",
      "family": "standardA0_A7Family"
    },
    {
      "resourceType": "virtualMachines",
      "locations": [
        "westus"
      ],
      "capabilities": [
        {
          "name": "MaxResourceVolumeMB",
          "value": "71680"
        },
        {
          "name": "OSVhdSizeMB",
          "value": "1047552"
        },
        {
          "name": "vCPUs",
          "value": "1"
        },
        {
          "name": "HyperVGenerations",
          "value": "V1"
        },
        {
          "name": "MemoryGB",
          "value": "1.75"
        },
        {
          "name": "MaxDataDiskCount",
          "value": "2"
        },
        {
          "name": "LowPriorityCapable",
          "value": "True"
        },
        {
          "name": "PremiumIO",
          "value": "False"
        },
        {
          "name": "vCPUsAvailable",
          "value": "1"
        },
        {
          "name": "ACUs",
          "value": "100"
        },
        {
          "name": "vCPUsPerCore",
          "value": "1"
        },
        {
          "name": "EphemeralOSDiskSupported",
          "value": "False"
        },
        {
          "name": "AcceleratedNetworkingEnabled",
          "value": "False"
        },
        {
          "name": "RdmaEnabled",
          "value": "False"
        },
        {
          "name": "MaxNetworkInterfaces",
          "value": "2"
        }
      ],
      "locationInfo": [
        {
          "location": "westus",
          "zones": [
            "1",
            "2",
            "3"
          ]
        }
      ],
      "name": "Standard_A1",
      "tier": "Standard",
      "size": "A1",
      "family": "standardA0_A7Family"
    }
      ],
      "nextLink": null
    }
    $Skus = ConvertFrom-Json $Json # $Json = '<paste the above json snippet>'
    

    What is the path (reference) to each (leaf) node in this graph-object?

    $Skus | Get-ChildNode -Recurse -Leaf
    
    Path                                                          Name         Depth Value
    ----                                                          ----         ----- -----
    value[0].resourceType                                         resourceType     3 virtualMachines
    value[0].locations[0]                                         0                4 westus
    value[0].capabilities[0].name                                 name             5 MaxResourceVolumeMB
    value[0].capabilities[0].value                                value            5 20480
    value[0].capabilities[1].name                                 name             5 OSVhdSizeMB
    value[0].capabilities[1].value                                value            5 1047552
    value[0].capabilities[2].name                                 name             5 vCPUs
    value[0].capabilities[2].value                                value            5 1
    ...
    

    Each path that is listed above might be used the get to the specific node in the object-graph, e.g.:

    $Skus.value[0].capabilities[0].name

    returns:

    MaxResourceVolumeMB
    

    As you probably want to get programmatically (dynamically) to this property you might use the Invoke-Expression command to get to the value of this property:

    $Path = 'value[0].capabilities[0].name'
    Invoke-Expression "`$Skus.$Path"
    MaxResourceVolumeMB
    

    But as mentioned in this helpful related answer from mklement0:

    for security reasons, Invoke-Expression (iex) is otherwise best avoided.

    So, you might also consider to use the object-graph tools to safely get to the specific node:

    $Path = 'value[0].capabilities[0].name'
    $Skus | Get-Node $Path
    

    This will give you a node (PSNode class) in return:

    Path                          Name Depth Value
    ----                          ---- ----- -----
    value[0].capabilities[0].name name     5 MaxResourceVolumeMB
    

    Or using a more advanced Extended Dot-Notation (Xdn) path:

    $Skus | Get-Node value.name=Standard_A0..~Name=vCPUs..Value
    
    Path                           Name  Depth Value
    ----                           ----  ----- -----
    value[0].capabilities[2].value value     5 1
    

    To get to the Value contained by the node:

    $Node = $Skus | Get-Node $Path
    $Node.Value
    MaxResourceVolumeMB
    

    The node value refers to the same value as you original object-graph. Meaning, you might simply change the value like this:

    $Node.Value = 'Updated Value"
    

    To confirm this, check your original $Skus object:

    $Skus | ConvertTo-Json # or: $Node.RootNode.Value | ConvertTo-Json
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search