Private/get-clusterHealthScore.ps1
# function Get-ClusterHealthScore { # param ( # [array]$Checks # ) # $validChecks = $Checks | Where-Object { # $_.Weight -ne $null -and $_.Total -ne $null # } # if (-not $validChecks) { # Write-Host "⚠️ No valid checks found." -ForegroundColor Red # return 0 # } # $maxScore = ($validChecks | Measure-Object -Property Weight -Sum).Sum # $earnedScore = ($validChecks | Where-Object { $_.Total -eq 0 } | Measure-Object -Property Weight -Sum).Sum # $score = [math]::Round(($earnedScore / $maxScore) * 100) # return $score # } # function Get-ClusterHealthScore { # param ( # [array]$Checks # ) # # only keep checks that declare a weight and have a Total count # $validChecks = $Checks | Where-Object { $_.Weight -ne $null -and $_.Total -ne $null } # # total possible weight sum # $maxScore = ($validChecks | Measure-Object Weight -Sum).Sum # # compute earned score contribution per check with diminishing returns: # # contribution = Weight * (1 - Total/(Total+1)) = Weight/(Total+1) # $earnedScore = 0 # foreach ($chk in $validChecks) { # $t = [int]$chk.Total # $w = [double]$chk.Weight # $earnedScore += $w * (1 - ($t / ($t + 1))) # } # # final percentage score # if ($maxScore -gt 0) { # return [math]::Round(($earnedScore / $maxScore) * 100) # } # else { # return 0 # } # } function Get-ClusterHealthScore { param ( [array]$Checks ) # map severities to numeric weights (case-insensitive keys) $severityWeights = @{ 'critical' = 3 'warning' = 2 'info' = 1 } # include checks with Weight and either Findings or Total count $validChecks = $Checks | Where-Object { $_.Weight -ne $null -and ($_.Findings -ne $null -or $_.Total -ne $null) } # total possible weight $maxWeight = ($validChecks | Measure-Object Weight -Sum).Sum # compute earned score with severity-based diminishing returns $earned = 0.0 foreach ($chk in $validChecks) { # determine severity sum: use Findings if present, else use Total as count of Info-level issues if ($null -ne $chk.Findings) { $sevSum = ($chk.Findings | ForEach-Object { $sevKey = $_.Severity?.ToString().ToLower() if ($sevKey -and $severityWeights.ContainsKey($sevKey)) { $severityWeights[$sevKey] } else { $severityWeights['info'] } } | Measure-Object -Sum).Sum } else { # treat each total count as Info-level issues $sevSum = [int]$chk.Total } # each check contributes Weight/(SeveritySum+1) $earned += ($chk.Weight / ($sevSum + 1)) } # final score as percentage of max possible if ($maxWeight -gt 0) { return [math]::Round(($earned / $maxWeight) * 100) } else { return 0 } } |