Functions/Private/Measure-CsvHappiness.ps1
|
function Measure-CsvHappiness { <# .SYNOPSIS Scores a Cluster Shared Volume on a 0–100 Happiness scale. .DESCRIPTION Two sub-scores are combined according to the caller-supplied weights. Space Happiness — based on the percentage of free space: >= 40% free → 100 20–40% free → linear 50–100 (50 + (freePct – 20) * 2.5) 10–20% free → linear 0–50 ((freePct – 10) * 5) < 10% free → 0 IO Happiness — based on average disk transfer latency (LatencyMs): <= 5 ms → 100 5–20 ms → linear 100–0 (100 – (latency – 5) * 6.667) > 20 ms → 0 When LatencyMs is $null (counter unavailable), the IO weight is dropped and the score normalises to pure space happiness. This ensures no CSV is penalised just because performance counters are unavailable. .OUTPUTS PSCustomObject: CsvName, SpaceHappiness, IoHappiness (nullable), HappinessScore #> [CmdletBinding()] param( [Parameter(Mandatory)] [PSCustomObject] $CsvMetrics, [ValidateRange(0.0, 1.0)] [float] $SpaceWeight = 0.7, [ValidateRange(0.0, 1.0)] [float] $IoWeight = 0.3 ) # ── Space happiness ──────────────────────────────────────────────────────── $freePct = if ($CsvMetrics.TotalGB -gt 0) { ($CsvMetrics.FreeGB / $CsvMetrics.TotalGB) * 100.0 } else { 100.0 } $spaceHappy = if ($freePct -ge 40.0) { 100.0 } elseif ($freePct -ge 20.0) { 50.0 + ($freePct - 20.0) * 2.5 } elseif ($freePct -ge 10.0) { ($freePct - 10.0) * 5.0 } else { 0.0 } # ── IO happiness (latency-based, optional) ───────────────────────────────── $ioHappy = $null if ($null -ne $CsvMetrics.LatencyMs) { $lat = [float]$CsvMetrics.LatencyMs $ioHappy = if ($lat -le 5.0) { 100.0 } elseif ($lat -le 20.0) { 100.0 - ($lat - 5.0) * (100.0 / 15.0) } else { 0.0 } } # ── Combined score ───────────────────────────────────────────────────────── $effectiveIoWeight = if ($null -ne $ioHappy) { $IoWeight } else { 0.0 } $totalWeight = $SpaceWeight + $effectiveIoWeight $score = if ($totalWeight -gt 0) { $ioTerm = if ($null -ne $ioHappy) { $ioHappy } else { 0.0 } ($spaceHappy * $SpaceWeight + $ioTerm * $effectiveIoWeight) / $totalWeight } else { $spaceHappy } [PSCustomObject]@{ CsvName = $CsvMetrics.Name SpaceHappiness = [Math]::Round($spaceHappy, 1) IoHappiness = if ($null -ne $ioHappy) { [Math]::Round($ioHappy, 1) } else { $null } HappinessScore = [Math]::Round($score, 1) } } |