Reputation: 299
I'm enumerating through all of the datastores in our VMware environment to get names and used space.
When I run the foreach
loop, it's both enumerating through the array, and not enumerating through the array.
Here's my script:
$list = @()
$row = '' | select Name, UsedSpace
$datastores = Get-Datastore
foreach ($store in $datastores) {
$row.name = $store.name;
$row.usedspace = [math]::Round(($store.extensiondata.summary.capacity - $store.extensiondata.summary.freespace)/1gb)
Write-Host $row; #To Verify that each row is different, and that enumeration is working#
$list += $row;
}
Console Output:
@{name=datastore1; usedspace=929} @{name=datastore2; usedspace=300} @{name=datastore3; usedspace=400}
$list
variable output:
Name Usedspace Datastore3 400 Datastore3 400 Datastore3 400
So it's enumerating through. getting all the correct data. but for some reason the line $list += $row
is waiting until the last object in the array, grabs only that data, but knows that there's 3 objects in the array, and populates each index with that objects data.
The only thing I've done to troubleshoot is bounced my PowerShell console.
Upvotes: 2
Views: 55
Reputation:
Alternatively you could create a PSCustomObject
$list = foreach ($store in Get-Datastore) {
[PSCustomObject]@{
Name = $store.name
UsedSpace = [math]::Round(($store.extensiondata.summary.capacity -
$store.extensiondata.summary.freespace)/1gb)
}
}
$list
As mentioned in the comments, with:
$row = '' | select Name, UsedSpace; $row.GetType()
you implicitly also create an (empty) PSCustomObject,
but as this needs to be created in every iteration of the foreach and then (inefficiently) appended to $list by rebuilding the array - directly building the PSCustomObject is IMO more clear / straight forward.
Upvotes: 1
Reputation: 47792
The reason for this is that $row
is a single object. You created it once, and then you keep changing the values of its properties. When you add it to the array, you're adding a reference to it, not a copy. So the values seen will always be those that were most recently set.
Recreate your $row
on every iteration of the loop.
Upvotes: 4