six demon bag
Wind, fire, all that kind of thing!
2014-02-26
A Bar Graph for the PowerShell Console
As a sysadmin I frequently have the need to get an overview of the utilization of particular system resources (disk space or memory for instance). Visualizing the numbers greatly helps with spotting bottlenecks.
One way to visualize data with PowerShell are DataVisualization
objects in Windows Forms, which are rather versatile, but not exactly what I
would consider straightforward. They also might be overkill for various tasks.
The current usage of a system resource for instance could easily be displayed
with a bar graph in a text console.
Jeffrey Hicks wrote a nifty PowerShell function which does just that. However, there are some details about it that I'd rather have differently:
- Print just the bar for a single value instead of the entire graph. That would also allow me to build captions from more than just one property without having to resort to calculated properties.
- Use a fixed default width that can be overridden by the caller instead of always using the entire width of the console window.
- Optionally display the percent value on the bar (the box graphic characters used by the original function prevent that).
- Optionally display additional information on the right side of the graph.
So this is what I came up with:
function Out-Gauge {
[CmdletBinding()]
Param(
[parameter(Mandatory=$true)][string]$Caption,
[parameter(Mandatory=$true)][double]$Value,
[string]$Info = '',
[int]$CaptionWidth = 20,
[int]$GaugeWidth = 60,
[int]$WarningLimit = 70,
[int]$CriticalLimit = 90,
[ConsoleColor[]]$OKColors = @([ConsoleColor]::Green, [ConsoleColor]::Black),
[ConsoleColor[]]$WarningColors = @([ConsoleColor]::Yellow, [ConsoleColor]::Black),
[ConsoleColor[]]$CriticalColors = @([ConsoleColor]::Red, [ConsoleColor]::White),
[switch][bool]$ShowValue = $false
)
# set foreground and background color for the bar
if ($Value -lt $WarningLimit) {
$bgColor = $OKColors[0]
$fgColor = $OKColors[1]
} elseif ($Value -lt $CriticalLimit) {
$bgColor = $WarningColors[0]
$fgColor = $WarningColors[1]
} else {
$bgColor = $CriticalColors[0]
$fgColor = $CriticalColors[1]
}
# calculate bar width
if ( $ShowValue ) {
$gauge = " {0,-$($GaugeWidth - 1):p}" -f ($Value / 100)
} else {
$gauge = ' ' * $GaugeWidth
}
$filled = [int]($Value / 100 * $GaugeWidth)
# print caption
Write-Host ("{0,-$CaptionWidth} {1}" -f $Caption, ([string][char]9474)) -NoNewline
# print bar
Write-Host $gauge.SubString(0, $filled) -Foreground $fgColor -Background $bgColor -NoNewline
Write-Host $gauge.SubString($filled) -NoNewline
# print info text
Write-Host ("{0} {1}" -f ([string][char]9474), $Info)
}
With this I can build a function for showing the used disk space of cluster shared volumes like this:
function Show-CsvUsage {
[CmdletBinding()]
Param(
[parameter(Mandatory=$true)][string]$Cluster
)
Get-ClusterSharedVolume -Cluster $Cluster | sort Name | % {
$caption = "{0,-7} ({1})" -f (Split-Path -Leaf $_.SharedVolumeInfo.FriendlyVolumeName), $_.Name
$value = 100.0 -$_.SharedVolumeInfo.Partition.PercentFree
$size = "{0:n2} TB" -f ($_.SharedVolumeInfo.Partition.Size / 1TB)
Out-Gauge -Caption $caption -Value $value -Info $size -ShowValue
}
}
Posted 23:38 [permalink]