Alex R.
Alex R.

Reputation: 467

Extract an array from an object and do calculation

I have this kind of an object:

enter image description here

How can I extract each quota and do calculation with used? I tried this

foreach($quota in $LKPQuotas.quotas) {
    foreach($zone in $quota) {
        $totalUsed += $zone.used 
    }
}

But it wont work for me. $LKPQuotas equals to $quota and $zone, and I do not understand why.

I can do calculation manually with code below, but I believe, that there is the other way.

foreach($zone in $LKPQuotas.quotas.volume_gigabytes_basic) {
    $volume_gigabytes_basic += $zone.used
}

Please, help me with that. Thank you and stay safe, pandemic is really hard.

Upvotes: 1

Views: 159

Answers (2)

Andrei Odegov
Andrei Odegov

Reputation: 3429

Creating test data:

$val = {Get-Random -Minimum 1000 -Maximum 2000}
$used = {Get-Random -Minimum 100 -Maximum 900}
$LKPQuotas = [PSCustomObject]@{
  quotas = [PSCustomObject]@{
    volume_gigabytes_basic = @(
      [PSCustomObject]@{value=&$val; used=& $used},
      [PSCustomObject]@{value=&$val; used=& $used},
      [PSCustomObject]@{value=&$val; used=& $used}
    )
    volume_gigabytes_fast = @(
      [PSCustomObject]@{value=& $val; used=& $used},
      [PSCustomObject]@{value=& $val; used=& $used},
      [PSCustomObject]@{value=& $val; used=& $used}
    )
    images_gigabytes = @(
      [PSCustomObject]@{used=& $used},
      [PSCustomObject]@{used=& $used},
      [PSCustomObject]@{used=& $used}
    )
    compute_cores = @(
      [PSCustomObject]@{sockets=1; cores=8},
      [PSCustomObject]@{sockets=4; cores=4}
    )
  }
}
$LKPQuotas | ConvertTo-Json

Output of test data:

{
    "quotas":  {
                   "volume_gigabytes_basic":  [
                                                  "@{value=1225; used=123}",
                                                  "@{value=1746; used=274}",
                                                  "@{value=1747; used=409}"
                                              ],
                   "volume_gigabytes_fast":  [
                                                 "@{value=1252; used=404}",
                                                 "@{value=1325; used=438}",
                                                 "@{value=1048; used=820}"
                                             ],
                   "images_gigabytes":  [
                                            "@{used=613}",
                                            "@{used=690}",
                                            "@{used=278}"
                                        ],
                   "compute_cores":  [
                                         "@{sockets=1; cores=8}",
                                         "@{sockets=4; cores=4}"
                                     ]
               }
}

Processing test data and getting results:

$valprops = @{N='value'; E={[uint32]$_.value}},
            @{N='used'; E={[uint32]$_.used}}
$LKPQuotas.quotas.psobject.Properties |
  ForEach-Object -Process {$prop = $_.Name
                           $psobj = [ordered]@{Name=$prop}
                           $LKPQuotas.quotas.$prop |
                           Select-Object -Property $valprops |
                             Measure-Object -Property value,used -Sum |
                             ForEach-Object -Process {$psobj[$_.Property]=$_.Sum}
                           [PSCustomObject]$psobj}

Output of results:

Name                   value used
----                   ----- ----
volume_gigabytes_basic  4718  806
volume_gigabytes_fast   3625 1662
images_gigabytes           0 1581
compute_cores              0    0

Upvotes: 1

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174465

foreach() doesn't magically enumerate all properties on an object.

You'll need to do something like:

# Create hashtable that will hold aggregates for each volume
$quotaStats = @{}

# loop through each volume
foreach($property in $LKPQuotas.quotas.psobject.Properties){
  $VolumeName = $property.Name

  # Create new object object to hold the results for this volume
  $quotaStats[$VolumeName] = [pscustomobject]@{
    VolumeName = $VolumeName
    TotalUsed = 0
    TotalAllowed = 0
  }

  # Collect and aggregate stats for each zone
  foreach($zone in $property.Value){
   $quotaStats[$VolumeName].TotalUser += $zone.used
   $quotaStats[$VolumeName].TotalAllowed += $zone.value
  }
}

After which $quotaStats will contain exactly one entry per volume, with the totals for every zone

Upvotes: 1

Related Questions