Skip to content
Menu
The Lonely Administrator
  • PowerShell Tips & Tricks
  • Books & Training
  • Essential PowerShell Learning Resources
  • Privacy Policy
  • About Me
The Lonely Administrator

Friday Fun Drive Usage Console Graph

Posted on December 9, 2011

I think you'll like this. Normally, I prefer my PowerShell commands to write objects to the pipeline. But there's nothing wrong with sending output directly to the console, as long as you know that the output is intended only for the screen. What I find frustrating is the use of Write-Host when really, pipelined objects would be better. But for today, I'm going to revel in the beauty of the console and create a colorized drive utilization graph.

Manage and Report Active Directory, Exchange and Microsoft 365 with
ManageEngine ADManager Plus - Download Free Trial

Exclusive offer on ADManager Plus for US and UK regions. Claim now!

The color will come from the BackgroundColor or ForegroundColor properties of Write-Host. For example, try this command in your PowerShell session:

[cc lang="PowerShell"]
PS C:\> write-host (" "*30) -BackgroundColor Yellow
[/cc]

The command is creating a "string" of 30 spaces. See where I'm going with this? Using WMI I can get drive usage information and turn it into values that I can "graph" using Write-Host. Here's the code I'm working with:

[cc lang="PowerShell"]
#requires -version 2.0

Param (
[string[]]$computers=@("computera","computerb","computerc")
)

#get the current window width so that our lines will be proportional
$Width = $Host.UI.RawUI.BufferSize.Width/2

$data=get-wmiobject -Class Win32_logicaldisk -filter "drivetype=3" -computer $computers

#get length of longest computername so we can pad
$longest=$data | select -ExpandProperty SystemName | sort Length | select -last 1

#group data by computername
$groups=$Data | Group-Object -Property SystemName

Clear-Host
Write-Host ("`n{0} {1}`n" -f "Disk Drive Report",(Get-Date)) -ForegroundColor Yellow

#iterate through each group object
ForEach ($computer in $groups) {

#define a collection of drives from the group object
$Drives=$computer.group

#iterate through each drive on each computer
Foreach ($drive in $drives) {
$FreeDividedSize=$drive.FreeSpace/$drive.Size
[string]$PerFree="{0:P}" -f $FreeDividedSize
[int]$FreePad=$Width*$FreeDividedSize

$Used=$drive.Size - $drive.Freespace
$UsedDividedSize=$used/$drive.Size
[string]$perUsed="{0:P}" -f $UsedDividedSize
[int]$UsedPad=$Width*$UsedDividedSize

#not currently used
[string]$UsedGB="{0:N2}GB " -f ($Used/1GB)
[string]$FreeGB="{0:N2}GB " -f ($drive.FreeSpace/1GB)

#this is the graph character
[string]$g=[char]9608
[string]$freeGraph=$g*($FreePad)
[string]$UsedGraph=$g*($UsedPad)

write-host ("[{0}] {1} " -f $drive.systemname.PadRight($longest.length),$drive.DeviceID) -NoNewline
write-host $freeGraph -ForegroundColor darkgreen -NoNewline
write-host $UsedGraph -ForegroundColor red -NoNewline
write-host (" {0} free " -f $PerFree)

#insert a return between each drive
write-host "`r"
} #foreach drive
#insert a blank line between computers if you want
#Write-host "`n"
} #foreach computer
[/cc]

Because I will need to adjust my graph to accommodate the width of the PowerShell window, I'm going to retrieve the console width and divide by 2. This will give me plenty of room to fit in the other output and still make a nice looking graph.

[cc lang="PowerShell"]
#get the current window width so that our lines will be proportional
$Width = $Host.UI.RawUI.BufferSize.Width/2
[/cc]

The script takes a collection of computer names and retrieves fixed logical disk information via WMI.

[cc lang="PowerShell"]
$data=get-wmiobject -Class Win32_logicaldisk -filter "drivetype=3" -computer $computers
[/cc]

Because I'm most likely going to be reporting on a group of computers, I want to include the computer name in the output. And because I want to keep everything proportional, I need to find the longest computer name. For all other names, I'll pad their names to equal the longest name. You'll see.

[cc lang="PowerShell"]
#get length of longest computername so we can pad
$longest=$data | select -ExpandProperty SystemName | sort Length | select -last 1
[/cc]

After a bit of experimentation, I decided the best way to process the data was to group it based on computer name, so I pipe it to Group-Object, grouping on the computername (systemname) property.

[cc lang="PowerShell"]
#group data by computername
$groups=$Data | Group-Object -Property SystemName
[/cc]

Now for the report. For every computer in the group, I'm going to enumerate every logical drive, get some stats and graph them. I didn't have to group them, but for a number of reasons, as well as showing you how to use the cmdlet, I decided to. When I piped the WMI results to Group-Object, I got a new object type. The object has a Group property which will be the collection of objects that have been grouped based on the property name, in my case, SystemName. Thus the Group property is a collection of Win32_LogicalDisk objects.

[cc lang="PowerShell"]
#iterate through each group object
ForEach ($computer in $groups) {
#define a collection of drives from the group object
$Drives=$computer.group
[/cc]

Now I can run some calculations and format the size and freespace properties. I'll be using these values with Write-Host.

[cc lang="PowerShell"]
#iterate through each drive on each computer
Foreach ($drive in $drives) {
$FreeDividedSize=$drive.FreeSpace/$drive.Size
[string]$PerFree="{0:P}" -f $FreeDividedSize
[int]$FreePad=$Width*$FreeDividedSize

$Used=$drive.Size - $drive.Freespace
$UsedDividedSize=$used/$drive.Size
[string]$perUsed="{0:P}" -f $UsedDividedSize
[int]$UsedPad=$Width*$UsedDividedSize

#not currently used
[string]$UsedGB="{0:N2}GB " -f ($Used/1GB)
[string]$FreeGB="{0:N2}GB " -f ($drive.FreeSpace/1GB)
[/cc]

Notice I'm using the -f operator to construct new strings, and format data. The qualifiers P and N will format the value as percent and a number, respectively. I originally planned in including the usage values directly in the bar chart, but it skewed the proportions. Instead, I decided to use a character and repeat it X number of times as necessary to reflect the amount of free space and amount used. I picked a block character, although I could have just used a space.

[cc lang="PowerShell"]
#this is the graph character
[string]$g=[char]9608
[string]$freeGraph=$g*($FreePad)
[string]$UsedGraph=$g*($UsedPad)
[/cc]

Armed with these values, I can now use Write-Host to create the graph. Because I want to graph system information, free space and usage on the same line, I tell Write-Host to not create a new line. The first part writes the computer name in square brackets. I'm also padding the computer name with empty spaces at the end so that the brackets all line up. After the computer name is the drive letter, or device ID.

[cc lang="PowerShell"]
write-host ("[{0}] {1} " -f $drive.systemname.PadRight($longest.length),$drive.DeviceID) -NoNewline
[/cc]

Remember, this is all on the same line. So next I "graph" usage using the -Foregroundcolor parameter.

[cc lang="PowerShell"]
write-host $freeGraph -ForegroundColor darkgreen -NoNewline
write-host $UsedGraph -ForegroundColor red -NoNewline
[/cc]

The last part writes the percent free value. At this point I have nothing else to write on the line so I'll let Write-Host insert a return.

[cc lang="PowerShell"]
write-host (" {0} free " -f $PerFree)
[/cc]

I toyed with a number of spacing options but ended up inserting a return after every result.

[cc lang="PowerShell"]
#insert a return between each drive
write-host "`r"
[/cc]

The final script can be run like this:

[cc lang="DOS"]
PS C:\> S:\demo-colorgraph.ps1 "client2","coredc01","server01"
[/cc]

Here's the end result:

If you need a quick visual check, this works just fine. However, because nothing is written to the pipeline all you can do is look; but sometimes that is enough. If nothing else, maybe you picked up a few PowerShell tidbits that might help in your own work.

You can download demo-colorgraph.ps1 to kick around. As with all my Friday Fun posts, this is not intended as a production ready, or even production worthy script, but rather something to have a little fun with and learn something new along the way. Enjoy.


Behind the PowerShell Pipeline

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on Mastodon (Opens in new window) Mastodon
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Pocket (Opens in new window) Pocket
  • Click to share on Reddit (Opens in new window) Reddit
  • Click to print (Opens in new window) Print
  • Click to email a link to a friend (Opens in new window) Email

Like this:

Like Loading...

Related

10 thoughts on “Friday Fun Drive Usage Console Graph”

  1. Gene says:
    December 9, 2011 at 12:22 pm

    Awesome! Looking forward to messin’ with it.

  2. Josh Atwell says:
    December 9, 2011 at 12:57 pm

    This is awesome Jeff! Very cool! I can’t wait to play with it myself!

    1. Jeffery Hicks says:
      December 9, 2011 at 1:05 pm

      If you try this in the ISE, you’ll want to pick a different color than Yellow for the title text.

  3. Don C says:
    December 9, 2011 at 1:11 pm

    This is pretty slick and came just in time for something that I was getting ready to work on. Thanks.

  4. vinden says:
    December 12, 2011 at 2:59 am

    That’s just awesome. I am putting this in production straight away..totally ignoring your warnings.

    BTW Jeffrey, on a different note : I use ISE and keep having these weird color issues. I have a black background and yellow prompt. But every now and then the colors get messed up, for instance after an error in red is triggered. Then my prompt is cyan all of a sudden, or any other color, and the ISE maintains this until I restart it. I have no idea how to troubleshoot this.

    1. Jeffery Hicks says:
      December 12, 2011 at 7:52 am

      The first step in your problem is to document steps to reproduce it, both for yourself and others. Are you resetting the output pane using $psise.options?

  5. Jeffery Hicks says:
    December 12, 2011 at 1:35 pm

    Check out his format ps1xml file that goes along with with: http://poshcode.org/3090

  6. Yuriy Marin says:
    December 12, 2011 at 8:10 pm

    Jeffrey, this is awesome!!

  7. winter says:
    December 15, 2011 at 4:39 pm

    Very nice! Absolutely going in my function library!

  8. Pingback: Backup Exec 2012 Tape Usage Report with PowerShell « A Resting Sys Admin's Blog

Comments are closed.

reports

Powered by Buttondown.

Join me on Mastodon

The PowerShell Practice Primer
Learn PowerShell in a Month of Lunches Fourth edition


Get More PowerShell Books

Other Online Content

github



PluralSightAuthor

Active Directory ADSI Automation Backup Books CIM CLI conferences console Friday Fun FridayFun Function functions Get-WMIObject GitHub hashtable HTML Hyper-V Iron Scripter ISE Measure-Object module modules MrRoboto new-object objects Out-Gridview Pipeline PowerShell PowerShell ISE Profile prompt Registry Regular Expressions remoting SAPIEN ScriptBlock Scripting Techmentor Training VBScript WMI WPF Write-Host xml

©2025 The Lonely Administrator | Powered by SuperbThemes!
%d