Hey, Scripting Guy! Weekend Scripter: Using Windows PowerShell 2.0 to Display Color-Coded Output in a Table

Hey, Scripting Guy! Weekend Scripter: Using Windows PowerShell 2.0 to Display Color-Coded Output in a Table

  • Comments 3
  • Likes

 

Bookmark and Share

 

Microsoft Scripting Guy Ed Wilson here. Summer has finally hit Charlotte, North Carolina, in full force. It is 87 degrees outside, and the humidity is 78 percent. This makes for a very hot and sticky day. I do not enjoy being hot and sticky, and therefore decided it was the perfect time to spend some time inside writing scripts. My list of scripts to write that I keep on the white board in my office is growing rather long, and with the added incentive of the heat and the humidity outside, I could hear Windows PowerShell calling my name.

Recently, someone on Twitter asked how to display color-coded output inside a table using Windows PowerShell 2.0. In the past, I have seen this question come up from time to time, and I have even heard people state that it cannot be done. However, because you can use a script block to create custom column headings for tables in Windows PowerShell, I figured I could also generate custom colors.

I was writing the script using the Windows PowerShell ISE, and I wasted nearly an hour messing around with the output before I realized that the script simply would not work in the Windows PowerShell ISE. This is because of the way that the Windows PowerShell ISE displays output. There is an interesting blog post by the Windows PowerShell team about differences between the Windows PowerShell ISE and the Windows PowerShell console that is worth reading. It was written during the beta of Windows PowerShell 2.0 and has not been updated for the RTM, but it appears to be still relevant. The differences in behavior between the Windows PowerShell ISE and the Windows PowerShell console should always be kept in mind, and you must test your script in both environments to prevent annoying troubleshooting issues.

I added a simple test to see if the script is running in the Windows PowerShell ISE or if it is running in the Windows PowerShell console. If the script is running in the Windows PowerShell ISE, a message is displayed that states the script should be run in the Windows PowerShell console to display color output. The script then exits. This is shown here:

if($host.name -match "ise") { "Run in the console for color output." ; exit }

Next, the original color of the ForegroundColor property is stored in the $originalColor variable. This is shown here:

$originalColor = $Host.UI.RawUI.ForegroundColor

After the preliminaries are out of the way, the results of the Get-Process cmdlet are piped to the Format-Table cmdlet. The name property is displayed without modification, but a hash table is used to display a column named “alert”. The expression that is assigned to the alert column uses an if statement to see if the CPU time is greater than 1. If it is, the ForegroundColor is changed to cyan, and the CPU value is displayed. If the value is not greater than 1, the color is changed to yellow and the CPU value is displayed. This section of the code is shown here:

Get-Process |
Format-Table -Property name,
@{label = "alert" ; Expression = {
if ($_.cpu -ge 1) { $Host.ui.rawui.ForegroundColor = "cyan" ; $_.cpu }
ELSE { $Host.ui.rawui.foregroundcolor = "yellow" ; $_.cpu }
} #end expression
} #end hash

The last thing to do is to change the display property back to the original color. This is seen here.

$Host.UI.RawUI.ForegroundColor = $originalColor

The complete ColorAlertTable.ps1 script is shown here.

ColorAlertTable.ps1

if($host.name -match "ise") { "Run in the console for color output." }
$originalColor = $Host.UI.RawUI.ForegroundColor
Get-Process |
Format-Table -Property name,
@{label = "alert" ; Expression = {
if ($_.cpu -ge 1) { $Host.ui.rawui.ForegroundColor = "cyan" ; $_.cpu }
ELSE { $Host.ui.rawui.foregroundcolor = "yellow" ; $_.cpu }
} #end expression
} #end hash
$Host.UI.RawUI.ForegroundColor = $originalColor

When the script runs, the output is displayed that is shown in the following image.

Image of script output

 

If you want to know exactly what we will be looking at tomorrow, follow us on Twitter or Facebook. If you have any questions, send e-mail to us at scripter@microsoft.com or post them on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson and Craig Liebendorfer, Scripting Guys

 

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Is there a way to extend this color coding to just one column rather than the entire row? I tried adding the host.ui.rawui.foregroundcolor to each column but the last one in the row wins and the entire row becomes that color. The thought was you could have multiple alert items (CPU, Memory) and you could vary the color from green, yellow, red depending on threshold for that item whilst the Name column + header itself remains the default color.

  • Thanks for this great post. Is there a way to make each column a different color? i.e. Process name could be grey, CPU could be Yellow, Memory could be red based on different thresholds?

  • Thanks for the article and example.

    I tried your example code as-is and it works as described.  I then tried to apply that example to a specific use, and the result is the whole set of Format-Table output as all one color (and not necessarily the default foreground color).

    After much experimenting, I found that the behavior difference was related to my use of the -AutoSize parameter on the Format-Table cmdlet, where your example did not use -AutoSize.  When I add -AutoSize to your example, it no longer displays the colors as before.

    My best understanding of the resulting behavior is that it appears when -AutoSize is used with the selective color code approach, the entire Format-Table output will take on the color of the last line of output.

    Any suggestions on how to get selective colors approach and -AutoSize to cooperatively work together?

    Thanks,

    Scott R.