Graphing with the PowerShell Console

I’ve written before about using the PowerShell console as a graphing tool, primarily using Write-Host. Most of what I’ve published before were really proof of concept. I decided to try and come up with a more formal and re-usable tool that could create a horizontal bar graph based on a numeric property from piped objects. For example, I wanted to get all processes and display a graph of the WorkingSet for each object. My result is an advanced function that should work in v2 or v3 called Out-ConsoleGraph.

Here’s the code, minus, the comment-based help. I’ve commented the quote quite a bit so I won’t spend a lot of time explaining it in detail.

The function requires that PowerShell be running in STA mode, which shouldn’t really be an issue. The intent is that you will be piping objects to the function. You need to specify a property that you want to graph and an object property to use as the label or caption for each object. The default caption is the Name property which seems pretty common. The property you are graphing must have a numeric value. The function’s premise is to get the window width, then write the caption and a graph figure using the remaining available width. The function has a bit of code to calculate the longest caption value so that everything lines up and then determines how much space remains for graphing.

The graph is really more of a proportional representation as opposed to actual value. In short, I find the largest property value which essentially becomes the 100% mark. All other values are calculated as percentages and graphed accordingly. This might be easier to understand if you see it in action.

This is getting all non-Microsoft processes and creating a graph of the WorkingSet property.

out-consolegraph-1

The graph title and color are customizable via parameters. This should work for any type of object as long as you can have a numeric property.

out-consolegraph-2

This command will work in the PowerShell ISE but I think it works better in the PowerShell console. Remember, this command is NOT writing to the pipeline so all you can do is view the output.

Download Out-ConsoleGraph and let me know what you think.

Valentines Day PowerShell Fun

In case you missed some of the fun on Twitter and Google Plus, here are the PowerShell valentines I sent today. These are intended to be run from the PowerShell console, not the ISE. Also, depending on your console font, you might get slightly different results. I use Lucida Console.

 

 


#1
write-host (([char]3 -as [string])*14) -ForegroundColor red

#2
$s="Be My Valentine"
[string]$hrt=[char]3

$s.split() | foreach -begin {$a="" }{$a+= "$_$hrt"} -end {write-host $a -ForegroundColor Magenta}

#alternative
$s.split() | foreach {Write-Host $_ -nonewline -foregroundcolor Magenta; Write-Host $hrt -nonewline -ForegroundColor Red} -end {"`n"}

#3
Write-Host "U make my $([char]3) $([char]14)" -foregroundcolor magenta -backgroundcolor yellow

#variation from Josh Atwell
Write-Host "Wild thing!" -ForegroundColor Yellow -BackgroundColor Magenta
Start-Sleep -Seconds 1
Write-Host "U make my $([char]3) $([char]14)" -ForegroundColor magenta -BackgroundColor yellow

#4
write-host "$([char]12)$([char]3)$([char]11)=$([char]2)" -foregroundcolor red -backgroundcolor white

Download MoreValentines.ps1 But I recommend you accompany this with at least a bouquet of nice flowers.

Friday Fun PowerShell Valentines Day

With Valentine’s Day just around the corner, I thought I should help you out with your gift giving. Remember those bags of candy with the cute sayings like “Be Mine”? Here’s how you can create a “bag” of them using Windows PowerShell; perfect for that extra geeky significant other. Or maybe you’ll just have fun playing with this.

The first part of the script changes the console title. Nothing extra special there, in terms of PowerShell. Next, I’m defining an array of strings that will be “printed” on the “candy”. I’m also defining an array of colors that you can use with Write-Host. Some colors like Gray hardly seem romantic so I’m limiting my array to the “pretty” colors. Finally, the script prompts you for the number of candies to create.

The main part of the script is a Foreach-Object expression. I’m using the range operator (..) as a counter. Each number is piped to ForEach, but I’m not doing anything with it. What I am doing though is using other cmdlet parameters that you may not be used to seeing. Most of the time when we use ForEach-Object, the scriptblock is the -Process parameter value, which runs once for every object piped in. But in my script I’m also using the -Begin parameter. This scriptblockk executes once before any pipelined objects are processed. In my script I’m simply clearing the screen. In the process script block I’m using Write-Host to write a random string from the $Print array using a random foreground color from the $color array. I’m also using -NoNewLine because I want to fill the screen, (or bag in keeping with my analogy). If I didn’t, I’d get a list. But because I’m not writing a new line, when I’ve reached the maximum number of candies, the -End scriptblock runs which simply adds the necessary return.

Download Valentines.ps1

Happy Valentine’s Day.

Friday Fun: Output to 2 Places in 1

Today’s Friday Fun comes out of a short exchange I had yesterday with Hal Rottenberg on Google Plus. We were playing around with piping a PowerShell command to Clip.exe which dumps the output to the Windows Clipboard. I got to thinking about taking this a step further based on my needs as a writer. Often I’d like to see the results of a command and then copy and paste the results into whatever I’m working on. In other words, I need to TEE the output to two places.

PowerShell has a cmdlet called Tee-Object that follows this principal. The default behavior is to write output to the pipeline AND send it to a text file.


PS C:\> get-service | tee c:\work\svc.txt

I’ll see the results and save them to a text file. I can also use this cmdlet to save results to a variable.


PS C:\> get-service | tee c:\work\svc.txt

Status Name DisplayName
------ ---- -----------
Running AeLookupSvc Application Experience
Stopped ALG Application Layer Gateway Service
Stopped AppIDSvc Application Identity
Stopped Appinfo Application Information
...
Running wudfsvc Windows Driver Foundation - User-mo...
Stopped WwanSvc WWAN AutoConfig

PS C:\> $svc.count
196
PS C:\>

One approach I came up with to incorporate with Clip.exe was this:


PS C:\> get-service | tee -Variable svc | clip

I don’t get the results immediately to the screen; they are saved to the variable. But at the same time output has been directed to the Windows Clipboard. That could be useful. But you know me, I always have to tinker a bit more and I ended up with a function called Out-Tee.


Function Out-Tee {

[cmdletbinding()]

Param (
[Parameter(Position=0,Mandatory=$True,ValueFromPipeline=$True)]
[object[]]$InputObject,
[alias("foregroundcolor","fg")]
[string]$TextColor=$host.ui.rawui.ForegroundColor
)

Begin {
#define an empty array to hold piped in objects
[email protected]()
}

Process {
#add each piped in object to the array
$a+=$inputobject
}

End {
#write the array to the pipeline as a string then pass to Write-Host
$a | out-string | write-host -fore $textColor
#write the array again to Clip.exe
$a | clip
}

} #end function

This simple function takes a PowerShell expression and writes the results to the console using Write-Host and also to the clipboard. The default output will use the current console foreground color. But you can specify any other color that you would use with Write-Host. I even added some alias properties so you can use -foregroundcolor or -fg.

With this function I can see the result and have it dumped to the clipboard. Because the default text color is the same as my session, I don’t see any difference when using Out-Tee.


PS C:\> ps | where {$_.ws -gt 100mb} | out-tee

Or if I want to pretty it up, I can add a little color.


PS C:\> ps | where {$_.ws -gt 100mb} | out-tee -TextColor green

Of course, the clipboard is just text. But now I have something easier to use to save output to the clipboard so I can paste it into my documents, assuming I like the output I see on the screen. The one caveat is that this function only works with successful commands. Errors, warnings, or verbose statements won’t get dumped to the clipboard. I can think of some ways around that which I might try in a future version. But for my immediate needs this works just fine.

Download Out-Tee and give it a try.

Friday Fun Drive Usage Console Graph

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. Continue reading