Creating a PS object

I am trying to create a list of all CPU/Memory combination and count each server type. That part works but when i am viewing my result i only get last server on all rows. I can’t figure out how to not write over each row. Any one that can point me in correct direction?

$var = get-vm sv* | select numcpu, memorygb | Group-Object numcpu,memorygb

$vmobjects = @()

$object = New-Object PSObject
Add-Member -InputObject $object -MemberType NoteProperty -Name Count -Value “”
Add-Member -InputObject $object -MemberType NoteProperty -Name CPU -Value “”
Add-Member -InputObject $object -MemberType NoteProperty -Name MemoryGB -Value “”

foreach ($row in $var)
{
$cpu,$mem = $row.name -split ‘,’, 2
$object.count = $row.count
$object.cpu = $cpu
$object.memorGB = $mem.trim()

$vmobjects += $object
}

$vmobjects

C:\Users\abc\Documents> $var

Count Name Group
----- ---- -----
1 4, 12 {@{NumCpu=4; MemoryGB=12}}
2 4, 8 {@{NumCpu=4; MemoryGB=8}, @{NumCpu=4; MemoryGB=8}}
1 4, 32 {@{NumCpu=4; MemoryGB=32}}
2 1, 4 {@{NumCpu=1; MemoryGB=4}, @{NumCpu=1; MemoryGB=4}}
1 4, 16 {@{NumCpu=4; MemoryGB=16}}
1 2, 4 {@{NumCpu=2; MemoryGB=4}}
1 4, 4 {@{NumCpu=4; MemoryGB=4}}
1 8, 24 {@{NumCpu=8; MemoryGB=24}}
1 2, 2 {@{NumCpu=2; MemoryGB=2}}
2 1, 2 {@{NumCpu=1; MemoryGB=2}, @{NumCpu=1; MemoryGB=2}}
1 4, 8,359375 {@{NumCpu=4; MemoryGB=8,359375}}

C:\Users\abc\Documents> $vmobjects

Count CPU MemoryGB
----- — --------
1 4 8,359375
1 4 8,359375
1 4 8,359375
1 4 8,359375
1 4 8,359375
1 4 8,359375
1 4 8,359375
1 4 8,359375
1 4 8,359375
1 4 8,359375
1 4 8,359375

 

Jonas,

Okay, did some quick testing for whatever reason the input method you are using is becoming corrupted. This is the solution I came up with. Let me know if this resolves the issue.

 

$var = get-vm sv* | select numcpu, memorygb | Group-Object numcpu,memorygb
$vmobjects = @()
foreach ($row in $var)
{
$cpu,$mem = $row.name -split ',', 2
$object = [pscustomobject][ordered] @{
Count = $row.count
CPU = $cpu
MemoryGB = $mem.trim()
}
$vmobjects += $object
}
$vmobjects

Thanks, now results shows expected values. Now I only need to figure out the differences between your working code and my code so I learn how to get it right next time.

You may want to consider simplifying the code in the foreach, which will improve performance.

Instead of creating an array ($vmobjects), concatenating new objects to it inside the foreach ($vmobjects += $object), and then returning the array afterwards ($vmobjects)… you can simply assign the foreach to a variable (without concatenation), and effectively remove the extra overhead:

$var = Get-VM sv* | Select-Object numcpu, memorygb | Group-Object numcpu, memorygb

$results = foreach ($row in $var) {
    $cpu, $mem = $row.Name -split ',', 2
    [pscustomobject]@{
        Count    = $row.Count
        CPU      = $cpu
        MemoryGB = $mem.Trim()
    }
}

Write-Output $results

Thanks for you input Aron. I ended up in putting the code in a function so i can filter out dirrent types of VMs in a easy way, for example Windows and Linux.

function get-numOfVms
{
param
(
[parameter(Mandatory = $true)]
[pscustomobject]$VMs
)

$results = foreach ($row in $var)
{
$cpu, $mem = $row.Name -split ',', 2
[pscustomobject]@{
NumOfVMs = $row.Count
NumOfCPUs = $cpu
MemoryGB = $mem.Trim()
}
}

return $results
}

If I may also suggest that when you post code, instead of selecting Format > Code, select your code and apply Preformatted (left of Bold formatting). It will appear as the code Jason and myself have posted, which makes reading it much easier and qualifies for quicker and more effective responses.