簡體   English   中英

使用PowerShell更新數組中的值

[英]Updating value in array with PowerShell

我正在為VMWare平台上的VM設計部署腳本,但是遇到了麻煩。

基本上,我的腳本這樣做:

從Excel接收信息,然后首先運行一些檢查。 在創建任何VM之前,它會為代表VM信息的每一行執行此操作。

驗證所有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中有多個VM時,存儲磁盤始終是相同的,因為可用磁盤空間尚未更新(因為尚未部署任何VM)。

我自己做了一些調查:

我必須找出一種更新FreeSpaceGB列的方法,但這是ReadOnly屬性。 然后,我雖然將每個項目推入我自己創建的另一個數組中,但這也不起作用。 仍為只讀屬性。 然后,我想到了將PSObjectAdd-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
}

UPDATE

我使用像@Ansgar建議的哈希表。 當我手動嘗試時,它可以正常工作,但是在我的腳本中卻不能。 當我在一個陣列中有多個VM時,將使用以前的數據存儲,並且剩余空間為UPDATED。

例:

VM1為120GB,使用VM-105。 該磁盤還剩299GB。
VM2為130GB,使用VM-105。 磁盤剩余289GB。

兩種VM都基於最大可用空間獲得了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
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM