我正在为VMWare平台上的虚拟机部署脚本工作,但我已经陷入困境。
基本上,我的脚本会这样做:
从Excel接收信息并首先运行一些检查。在创建任何VM之前,它会为每行代表VM信息。
验证所有虚拟机后,将创建第一个虚拟机,然后创建下一个虚拟机等。
我的一个功能是计算最佳可用存储磁盘。它返回具有最多可用磁盘空间的第一个存储磁盘。
该功能如下所示:
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
,但这是一个ReadOnly属性。
然后,我会推动我自己创建的另一个阵列中的每个项目,但这也不起作用。还是Readonly财产。
然后我考虑将PSObject
与Add-Member
一起使用,但我也无法解决这个问题(或者我做错了)。
$ownarray= @()
$item = New-Object PSObject
$Global:TotalFreeSpaceManagement = Get-Cluster -Name Management |
Get-Datastore |
where Name -notlike "*local*" |
sort FreeSpaceGB -Descending
foreach ($StorageDisk in $Global:TotalFreeSpaceManagement) {
$item | Add-Member -Type NoteProperty -Name "$($StorageDisk.Name)" -Value "$($StorageDisk.FreeSpaceGB)"
$ownarray += $item
}
更新
我使用像@Ansgar建议的哈希表。当我手动尝试它时,它完美地工作,但在我的脚本中却没有。 当我在阵列中有多个VM时,正在使用先前的数据存储区,并且剩下的空间是更新的。
示例:
VM1为120GB并使用VM-105。该磁盘剩余299GB VM2为130GB,使用VM-105。然后磁盘剩下289GB。
两个虚拟机都根据最多可用空间获得建议的VM-105。
VM-105应该有299 - 130 = 160GB左边是脚本工作正常但不知何故$FreeSpace
被更新,或$max
被覆盖,我无法弄清楚这是怎么发生的。
答案 0 :(得分:0)
您需要跟踪可用空间的更改,同时还要保持磁盘与计算的剩余可用空间之间的关联。为此,请将存储读入哈希表,该哈希表将磁盘与可用空间相关联。然后使用该哈希表选择磁盘并在放置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
}
}