Private/Show-CounterTable.ps1

function Show-CounterTable {
     [CmdletBinding()]
     param(
          [Parameter(Mandatory=$true)]
          [PerformanceCounter[]]$Counters
     )

     if ( $Counters.Count -eq 0 ) { return }

     # Create table data structure
     $tableData = @()

     foreach ( $Counter in $Counters ) {

          $Stats = $Counter.Statistics

          # Create row data
          $rowData = [PSCustomObject]@{
               Counter        = $Counter
               CounterName    = $Counter.Title
               Unit           = $Counter.Unit
               Current        = if ( $null -ne $Stats.Current )   { $Stats.Current }  else { "-" }
               Last5          = if ( $Stats.Last5.Count -gt 0 )   { $Stats.Last5 }    else { @() }
               Min            = if ( $null -ne $Stats.Minimum )   { $Stats.Minimum }  else { "-" }
               Max            = if ( $null -ne $Stats.Maximum )   { $Stats.Maximum }  else { "-" }
               Avg            = if ( $null -ne $Stats.Average )   { $Stats.Average }  else { "-" }
               ColorMap       = $Counter.colorMap
          }

          $tableData += $rowData

     }

     # Calculate column widths
     $widths = @{
          CounterName    = ($tableData | ForEach-Object { $_.CounterName.Length } | Measure-Object -Maximum).Maximum + 2
          Unit           = ($tableData | ForEach-Object { $_.Unit.Length } | Measure-Object -Maximum).Maximum + 2
          Current        = ($tableData | ForEach-Object { $_.Current.ToString().Length } | Measure-Object -Maximum).Maximum + 2
          Last5          = 0
          Min            = ($tableData | ForEach-Object { $_.Min.ToString().Length } | Measure-Object -Maximum).Maximum + 2
          Max            = ($tableData | ForEach-Object { $_.Max.ToString().Length } | Measure-Object -Maximum).Maximum + 2
          Avg            = ($tableData | ForEach-Object { $_.Avg.ToString().Length } | Measure-Object -Maximum).Maximum + 2
     }

     # Calculate Last5 width
     $maxLast5Count      = ($tableData | ForEach-Object { $_.Last5.Count } | Measure-Object -Maximum).Maximum
     $last5SubWidths     = @()

     for ( $pos = 0; $pos -lt $maxLast5Count; $pos++ ) {
          $maxWidthAtPos = 0
          foreach ( $row in $tableData ) {
               if ( $pos -lt $row.Last5.Count ) {
                    $valueLength = $row.Last5[$pos].ToString().Length
                    if ( $valueLength -gt $maxWidthAtPos ) {
                         $maxWidthAtPos = $valueLength
                    }
               }
          }
          $last5SubWidths += $maxWidthAtPos
     }

     # Calculate total Last5 width: sum of all sub-widths plus separators
     if ( $last5SubWidths.Count -gt 0 ) {
          $totalLast5Width = ($last5SubWidths | Measure-Object -Sum).Sum + (($last5SubWidths.Count - 1) * 3) # 3 chars for " | "
          $widths.Last5 = $totalLast5Width + 2
     } else {
          $widths.Last5 = $headers.Last5.Length + 2
     }

     # Ensure minimum widths for headers
     $headers = @{
          CounterName    = "Counter Name"
          Unit           = "Unit"
          Current        = "Current"
          Last5          = "Last 5 Values"
          Min            = "Min"
          Max            = "Max"
          Avg            = "Avg"
     }

     foreach ( $key in $headers.Keys ) {
          if ( $widths[$key] -lt ($headers[$key].Length + 2) ) {
               $widths[$key] = $headers[$key].Length + 2
          }
     }

     # Helper function to get color for value
     function Get-ValueColor {
          param($value, $colorMap)

          if ([string]::IsNullOrEmpty($value) -or $value -eq "-") {
               return "White"
          }

          $numericValue = 0
          if (![int]::TryParse($value, [ref]$numericValue)) {
               return "White"
          }

          $colorMapOrdered = [ordered]@{}
          $colorMap.Keys | Sort-Object | ForEach-Object {
               $colorMapOrdered.add($_, $colorMap[$_])
          }

          $color = for ( $b = 0; $b -lt $colorMapOrdered.Count; $b++ ) {
               $bound = $colorMapOrdered.Keys[$b]
               if ( $value -lt $bound ) {
                    $colorMapOrdered[$b]
                    break
               }
          }

          if ( [string]::IsNullOrEmpty($color) ) {
               $color = $colorMapOrdered[-1]
          }

          return $color
     }

     # Print header
     $headerLine = " {0} | {1} | {2} | {3} | {4} | {5} | {6} " -f `
          $headers.CounterName.PadRight($widths.CounterName - 2), `
          $headers.Unit.PadRight($widths.Unit - 2), `
          $headers.Current.PadRight($widths.Current - 2), `
          $headers.Last5.PadRight($widths.Last5 - 2), `
          $headers.Min.PadRight($widths.Min - 2), `
          $headers.Max.PadRight($widths.Max - 2), `
          $headers.Avg.PadRight($widths.Avg - 2)

     Write-Host $headerLine -ForegroundColor Cyan

     # Print separator line
     $separatorLine = "-" * $headerLine.Length
     Write-Host $separatorLine -ForegroundColor Gray

     # Print data rows
     foreach ( $row in $tableData ) {
          $currentColor  = Get-ValueColor -value $row.Current    -colorMap $row.ColorMap
          $minColor      = Get-ValueColor -value $row.Min        -colorMap $row.ColorMap
          $maxColor      = Get-ValueColor -value $row.Max        -colorMap $row.ColorMap
          $avgColor      = Get-ValueColor -value $row.Avg        -colorMap $row.ColorMap

          # Format Last5 values with colors
          $last5Formatted = ""
          if ( $row.Last5.Count -gt 0 ) {
               $last5Parts = @()
               foreach ( $value in $row.Last5) {
                    $last5Parts += $value
               }
               $last5Formatted = ($last5Parts -join " | ")
          } else {
               $last5Formatted = "-"
          }

          # Print row parts
          Write-Host -NoNewline (" {0} | " -f $row.CounterName.PadRight($widths.CounterName - 2)) -ForegroundColor White
          Write-Host -NoNewline ("{0} | " -f $row.Unit.PadRight($widths.Unit - 2)) -ForegroundColor White
          Write-Host -NoNewline ("{0} " -f $row.Current.ToString().PadRight($widths.Current - 2)) -ForegroundColor $currentColor
          Write-Host -NoNewline "| " -ForegroundColor White

          # Handle Last5 with individual colors
          if ( $row.Last5.Count -gt 0 ) {
               # Print Last5 values with individual coloring and proper sub-column widths
               for ( $i = 0; $i -lt $row.Last5.Count; $i++ ) {
                    $value = $row.Last5[$i]
                    $color = Get-ValueColor -value $value -colorMap $row.ColorMap

                    if ( $i -gt 0 ) {
                         Write-Host -NoNewline " | " -ForegroundColor White
                    }

                    # Pad value to its sub-column width
                    $paddedValue = $value.ToString().PadRight($last5SubWidths[$i])
                    Write-Host -NoNewline $paddedValue -ForegroundColor $color
               }

               # Calculate remaining space after all values and separators
               $usedSpace = ($last5SubWidths | Measure-Object -Sum).Sum + (($row.Last5.Count - 1) * 3)
               $remainingSpace = ($widths.Last5 - 2) - $usedSpace

               if ( $remainingSpace -gt 0 ) {
                    Write-Host -NoNewline (" " * $remainingSpace) -ForegroundColor White
               }

               Write-Host -NoNewline " | " -ForegroundColor White

          } else {

               Write-Host -NoNewline ("{0} | " -f "-".PadRight($widths.Last5 - 2)) -ForegroundColor White

          }          Write-Host -NoNewline ("{0} " -f $row.Min.ToString().PadRight($widths.Min - 2)) -ForegroundColor $minColor
          Write-Host -NoNewline "| " -ForegroundColor White
          Write-Host -NoNewline ("{0} " -f $row.Max.ToString().PadRight($widths.Max - 2)) -ForegroundColor $maxColor
          Write-Host -NoNewline "| " -ForegroundColor White
          Write-Host ("{0} " -f $row.Avg.ToString().PadRight($widths.Avg - 2)) -ForegroundColor $avgColor
     }

     Write-Host ""

}