Visualizing objects in the PowerShell console

Last week we talked about how to enhance time-based PowerShell objects by adding a duration. This provides useful metrics, but humans are visual by nature and it would help even more if we could visualize the numbers.  As with any task, I started my search for console visualizations by googling to see if anyone else had written something I could use.  I came across a blog post from Jeff Hicks in 2013 that showcased his PowerShell console graphing tool.  The console graphs were close to what I wanted to do, but in testing I found that dropping all of the other properties of the object didn't allow me to retain important and relevant data.

I set about modifying the function to my liking and ended up with the following changes:
  • Removed color-based conditional formatting for readability and ease-of-use
  • Modified the output to be object-based 
  • Added ability to specify columns to keep
The first modification ended up being more of a usability issue for me. My use-cases did not require changing colors of the graph and by removing this functionality, we reduce the complexity of the script and the number of mandatory properties.  Also, with the script leaner, it made my next tasks much easier.

In the process of updating the script, it became clear that meeting my requirement of retaining properties would also require returning objects instead of writing to the host.  After editing the code to maintain the objects passed into the function, it was simple enough to convert the Write-Host of the bars in the chart to instead add a new property with the bar as a string.

Once we had all of that code modified, I quickly realized that the more properties we specified and the greater the width of them, the less space we had for charting.  That's the exact opposite of the problem I originally had; now there's TOO much data!  By implementing my original requirement of being able to specify columns to keep, we are now actually restricting the data so that we can provide more helpful charts.

With the function complete, we can do fun things like chart the top 10 memory hogs:


And we can also get an idea of how many commands that PowerShell modules contain:



The Out-ConsoleGraph function is available on Github.



Enhancing time-based objects with duration

Often when troubleshooting we come across log files that have tons of data.  It can be hard to digest properly, so we look for tools that can break it down and provide some insight into what is happening.  Last week, I shared a blog post on parsing System Center logs with PowerShell.  If we use that function to convert the log lines into objects, we can now manipulate them and add calculated fields to provide even more data to assist in troubleshooting.

One of the important angles when troubleshooting is "How long did each task in the process take?". To answer this question, we need to take a look at each line in the logs and compare it to the following one.  With PowerShell, the pipeline processes each object one at a time, so how do we accomplish this with code?

The method that I came up with was to include a stutter-step for the pipeline.  Capture the first log line in a variable and hold onto it until the pipeline moves to the next entry.  We can then calculate the difference in the date/time fields and add it as a new property.  The second entry in the log then overwrites the first entry as the stored variable and we continue until the last entry in the log.  As it is the last entry in the log, we have nothing to compare it to, so we simply set it as a dash.



As you can see above, the Add-Duration function reads in the output of Get-CMLog, selects the UTCTime property for comparison, and adds the results to a property called TotalMilliseconds.

Depending on the duration of your logs, you may want to use one of the other options for duration such as Days, Hours, Minutes, or Seconds.  This is useful when troubleshooting long-running tasks such as OSD, or even when you just want to figure out what is taking a long time in the process so that you can track, trend, and reduce it.

And this function is not just for System Center logs.  It should work on any time-based object as long as you specify the property containing a [DateTime] field that New-TimeSpan can parse.

The full code is available below and on Github.