Arrays 使用PowerShell更新数组中的值
我正在为VMWare平台上的VM编写一个部署脚本,但我被卡住了 基本上,我的脚本是这样做的: 从Excel接收信息并首先运行一些检查。在创建任何VM之前,它会对每一行执行此操作,这将表示VM信息 验证所有虚拟机后,将创建第一个虚拟机,然后创建下一个虚拟机,以此类推 我的一个函数将计算最佳可用存储磁盘。它返回第一个具有最多可用磁盘空间的存储磁盘 该函数如下所示:Arrays 使用PowerShell更新数组中的值,arrays,powershell,powercli,Arrays,Powershell,Powercli,我正在为VMWare平台上的VM编写一个部署脚本,但我被卡住了 基本上,我的脚本是这样做的: 从Excel接收信息并首先运行一些检查。在创建任何VM之前,它会对每一行执行此操作,这将表示VM信息 验证所有虚拟机后,将创建第一个虚拟机,然后创建下一个虚拟机,以此类推 我的一个函数将计算最佳可用存储磁盘。它返回第一个具有最多可用磁盘空间的存储磁盘 该函数如下所示: Function Get-AvailableStorage { $Threshold = "80" # GB $Tota
Function Get-AvailableStorage {
$Threshold = "80" # GB
$TotalFreeSpace = Get-Cluster -Name Management |
Get-Datastore |
where Name -notlike "*local*" |
sort FreeSpaceGB -Descending
if ($SqlServices -notlike "NONE") {
$VMSize = 30 + $VMStorage + 10
} else {
$VMSize = 30 + $VMStorage
}
foreach ($StorageDisk in $TotalFreeSpace) {
[math]::floor($StorageDisk.FreeSpaceGB) | Set-Variable RoundedSpace
$FreeAfter = $RoundedSpace - $VMSize | sort -Descending
if ($FreeAfter -lt $Threshold) {
return $StoragePool = "VSAN"
} else {
return $StorageDisk.Name
}
}
}
问题
当我的Excel中有多个虚拟机时,存储磁盘总是相同的,因为没有更新可用磁盘空间(因为还没有部署任何虚拟机)
我自己做了一些调查:
我必须想办法更新列FreeSpaceGB
,但这是一个只读属性。
然后我想把每一项都推到我自己创建的另一个数组中,但这也不起作用。仍然是只读属性。
然后我考虑将PSObject
与Add成员一起使用,但我也无法让它工作(或者我做得不对)
更新
我像@Ansgar建议的那样使用哈希表。当我手动尝试时,它工作得很好,但在我的脚本中不是这样。
当我在一个数组中有多个VM时,将使用以前的数据存储,并更新剩余的空间
例如:
VM1是120GB,使用VM-105。该磁盘还剩下299GB。
VM2是130GB,使用VM-105。那么磁盘还剩下289GB
两个虚拟机都得到了基于最大可用空间的建议VM-105
VM-105应该还有299-130=160GB的空间。如果脚本工作正常,但不知何故,$FreeSpace
被更新了,或者$max
被覆盖了,我不知道这是如何发生的。您需要跟踪对可用空间的更改,同时还保持磁盘和计算出的剩余可用空间之间的关联。为此,将存储读入一个哈希表,该哈希表将磁盘和可用空间关联起来。然后使用该哈希表选择磁盘,并在放置VM时更新相应的可用空间值
$threshold = 80 # GB
# initialize global hashtable
$storage = @{}
Get-Cluster -Name Management | Get-Datastore | Where-Object {
$_.Name -notlike '*local*'
} | ForEach-Object {
$script:storage[$_.Name] = [Math]::Floor($_.FreeSpaceGB)
}
function Get-AvailableStorage([int]$VMSize) {
# find disk that currently has the most free space
$disk = ''
$max = 0
foreach ($key in $script:storage.Keys) {
$freespace = $script:storage[$key] # just to shorten condition below
if ($freespace -gt $max -and $threshold -lt ($freespace - $VMSize)) {
$max = $freespace
$disk = $key
}
}
# return storage and update global hashtable
if (-not $disk) {
return 'VSAN' # fallback if no suitable disk was found
} else {
$script:storage[$disk] -= $VMSize
return $disk
}
}
你需要一个数组列表。你必须加上这个。请检查我的回答中的arraylist@RanadipDutta,谢谢,但我仍然存在无法更新值的问题。执行此操作时:$array_list[1]。FreeSpaceMB='1'我的错误;'FreeSpaceMB'是一个只读属性。或者我不完全理解如何更新:),很抱歉,没有SetValue方法。有关更新代码的帮助信息:显示更新的代码。我刚刚修改了代码中的一个逻辑错误并再次测试,它完全符合我的预期;我不得不在$threshold和VMSize中使用双引号。否则它就无法工作,仍然需要计算哈希表的工作。我可以在存储中使用-xxx(因此没有存储空间了),但我试图弄清楚它是如何产生的:)我已经更新了我的问题,因为我现在遇到了另一个问题循环中的第二个条件确定要使用的磁盘是错误的。必须是-lt
,而不是-gt
。更新了我的答案。
$threshold = 80 # GB
# initialize global hashtable
$storage = @{}
Get-Cluster -Name Management | Get-Datastore | Where-Object {
$_.Name -notlike '*local*'
} | ForEach-Object {
$script:storage[$_.Name] = [Math]::Floor($_.FreeSpaceGB)
}
function Get-AvailableStorage([int]$VMSize) {
# find disk that currently has the most free space
$disk = ''
$max = 0
foreach ($key in $script:storage.Keys) {
$freespace = $script:storage[$key] # just to shorten condition below
if ($freespace -gt $max -and $threshold -lt ($freespace - $VMSize)) {
$max = $freespace
$disk = $key
}
}
# return storage and update global hashtable
if (-not $disk) {
return 'VSAN' # fallback if no suitable disk was found
} else {
$script:storage[$disk] -= $VMSize
return $disk
}
}