Functions/Private/Measure-VmHappiness.ps1
|
function Measure-VmHappiness { <# .SYNOPSIS Calculates a VM Happiness Score (0–100) based on CPU and memory resource satisfaction. .DESCRIPTION CPU Happiness: A VM is CPU-unhappy when the host is overloaded AND the VM is demanding CPU. Host CPU stress ramps linearly from 0 at 70% utilization to 1.0 at 100%. Happiness = 100 − (stress × VM CPU demand). Memory Happiness (Dynamic Memory): Based on Hyper-V Dynamic Memory pressure counter. Pressure ≤ 100 → fully happy (VM has what it needs or more). Pressure 100–150 → linearly degrades to 0. Pressure > 150 → fully unhappy. Memory Happiness (Static Memory): Proxied from host available memory. Host memory utilization ≤ 70% → fully happy. 70–90% → linearly degrades to 0. > 90% → fully unhappy. .OUTPUTS PSCustomObject with VMName, HostNode, CpuHappiness, MemHappiness, HappinessScore. #> [CmdletBinding()] param( [Parameter(Mandatory)] [PSCustomObject]$VmMetrics, [Parameter(Mandatory)] [PSCustomObject]$HostMetrics, [float]$CpuWeight = 0.5, [float]$MemoryWeight = 0.5 ) # ── CPU Happiness ────────────────────────────────────────────────────────── # Stress factor: 0 when host ≤ 70%, 1 when host = 100% $cpuStress = [Math]::Max(0.0, ($HostMetrics.CpuUtilization - 70.0) / 30.0) $cpuHappiness = [Math]::Max(0.0, [Math]::Min(100.0, 100.0 - ($cpuStress * $VmMetrics.CpuUtilization))) # ── Memory Happiness ─────────────────────────────────────────────────────── if ($VmMetrics.DynamicMemoryEnabled) { $p = $VmMetrics.MemoryPressure $memHappiness = if ($p -le 100) { 100.0 } elseif ($p -le 150) { 100.0 - (($p - 100.0) * 2.0) # 100 → 0 across the 100–150 range } else { 0.0 } } else { # Static memory: proxy from host memory utilization $hostMemUtil = (($HostMetrics.TotalMemoryMB - [Math]::Max(0, $HostMetrics.AvailableMemoryMB)) / $HostMetrics.TotalMemoryMB) * 100.0 $memHappiness = if ($hostMemUtil -le 70.0) { 100.0 } elseif ($hostMemUtil -le 90.0) { 100.0 - (($hostMemUtil - 70.0) * 5.0) # 100 → 0 across the 70–90% range } else { 0.0 } } $memHappiness = [Math]::Max(0.0, [Math]::Min(100.0, $memHappiness)) # ── Combined Score ───────────────────────────────────────────────────────── $totalWeight = $CpuWeight + $MemoryWeight $combined = (($cpuHappiness * $CpuWeight) + ($memHappiness * $MemoryWeight)) / $totalWeight [PSCustomObject]@{ VMName = $VmMetrics.VMName HostNode = $VmMetrics.HostNode CpuHappiness = [Math]::Round($cpuHappiness, 1) MemHappiness = [Math]::Round($memHappiness, 1) HappinessScore = [Math]::Round($combined, 1) } } |