我正在枚举VMware环境中的所有数据存储区,以获取名称和已用空间。
当我运行foreach
循环时,它既在数组中枚举,又不在数组中枚举。
这是我的剧本:
$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;
}
控制台输出:
@{name=datastore1; usedspace=929} @{name=datastore2; usedspace=300} @{name=datastore3; usedspace=400}
$list
变量输出:
Name Usedspace Datastore3 400 Datastore3 400 Datastore3 400
因此它正在枚举。获取所有正确的数据。但是由于某种原因,行$list += $row
一直等到数组中的最后一个对象,仅获取该数据,但知道数组中有3个对象,并使用该对象数据填充每个索引。
我唯一要解决的问题就是弹回PowerShell控制台。
答案 0 :(得分:4)
其原因是$row
是单个对象。您创建了一次,然后继续更改其属性的值。当您将其添加到数组时,您将在其中添加 reference 而不是副本。因此,看到的值将始终是最新设置的值。
在循环的每次迭代中重新创建$row
。
答案 1 :(得分:1)
或者,您可以创建一个PSCustomObject
$list = foreach ($store in Get-Datastore) {
[PSCustomObject]@{
Name = $store.name
UsedSpace = [math]::Round(($store.extensiondata.summary.capacity -
$store.extensiondata.summary.freespace)/1gb)
}
}
$list
如评论中所述,带有:
$row = '' | select Name, UsedSpace; $row.GetType()
您还隐式创建了一个(空的)PSCustomObject,
但是由于需要在foreach的每次迭代中都创建此代码,然后通过重建数组(低效地)将其附加到$ list中-直接构建PSCustomObject是IMO更加清楚/直接的做法。