Private/Measure-Percentile.ps1
|
function Measure-Percentile { <# .SYNOPSIS Computes a percentile from a numeric array using linear interpolation. .DESCRIPTION Platform metrics in Azure Monitor expose only Average/Min/Max/Count/Total -- there is no server-side percentile aggregation. This function computes percentiles client-side from the raw per-interval datapoints we pull back. Uses the same linear-interpolation-between-closest-ranks method as Kusto's percentile() (type C / "linear"), so values line up with VMPerformance(). .PARAMETER Value The numeric samples. Nulls are ignored. Order does not matter (sorted internally). .PARAMETER Percentile The percentile to compute, 0-100 (e.g. 95 for P95). .OUTPUTS [double] the interpolated percentile, or $null when no samples are supplied. .EXAMPLE Measure-Percentile -Value 1,2,3,4,5,6,7,8,9,10 -Percentile 95 #> [CmdletBinding()] [OutputType([double])] param( [Parameter(Mandatory)] [AllowEmptyCollection()] [AllowNull()] [double[]] $Value, [Parameter(Mandatory)] [ValidateRange(0, 100)] [double] $Percentile ) $samples = @($Value | Where-Object { $null -ne $_ } | Sort-Object) $n = $samples.Count if ($n -eq 0) { return $null } if ($n -eq 1) { return [double] $samples[0] } # Rank position on a 0-based index scale (linear interpolation, Kusto-compatible). $rank = ($Percentile / 100.0) * ($n - 1) $lower = [math]::Floor($rank) $upper = [math]::Ceiling($rank) if ($lower -eq $upper) { return [double] $samples[[int]$lower] } $weight = $rank - $lower return [double] ($samples[[int]$lower] * (1 - $weight) + $samples[[int]$upper] * $weight) } |