Friday Fun: Out-ConditionalColor

Last week I posted a Friday Fun article on parsing results from Invoke-Webrequest and displaying matching strings in color so that the book titles I’m interested in stand out. But the more I thought about it I realized I should take this a step further. The problem with Write-Host is that it doesn’t write anything to the pipeline which is why we typically frown upon its use. Although being able to use color to highlight something is very cool. I wanted color and pipelined output. Here’s my result.

This function only really works in the PowerShell console. It is designed to accept any PowerShell input. The function also takes parameters that help it write matching objects in the specified color. The easy way to use the function is to specify a property and a hashtable. The hashtable key is the value you want to match in the input and the key is the color you want to use. The function processes each object as it comes in and if the property matches the value it sets the foreground color of the console to the specified value.

If it doesn’t match then the foreground color essentially remains the same. This means I can run a command like this:

And get a result like this:

Any time the process name is equal to ‘chrome’ I display that object in yellow. You can also have multiple entries.

I mentioned match earlier but it is really a simple equality test. However, I also added code so that you could be even more granular.
You can also create what I refer to as a complex hashtable. This must be an ordered hashtable, which means you must be running PowerShell 3.0. Define a hashtable like this:

This is a little tricky. The hashtable key is a scriptblock of the object property you want to watch and some operator comparison. The value is the console color you want to use for the match. Use $psitem to represent the current object in the pipeline. The reason for the ordered hashtable is because the keys are processed in an If/ElseIf fashion so make sure you get things in the right order.

The function breaks apart the hashtable and builds a here string of the If/ElseIf structure in the Begin scriptblock.

The here string includes the commands to set the host foreground color. Then in the Process scriptblock I use Invoke-Expression to execute it.

But now I can do this.

When using a complex hashtable, there’s no need to specify a property. What’s great about all of this is that if you want to see the color output and still save the results, use the common -Outvariable parameter with Out-Conditionalcolor.

$P won’t be colorized (unless I run it through the function again), but I still have the data.

There are some limitations. Like any Out cmdlet, this must be the last command in your pipelined expression. Technically you could sort or filter after my function, but it will lose the conditional coloring. Unlike the other Out cmdlets, you cannot piped any formatted data to it.

The whole point of the function is to provide a means of adding some visual references to your PowerShell data.
occ-basic3I sincerely hope you’ll try this out and let me know what you think.

Get File Utilization by Extension

In the past I’ve posted a few PowerShell functions that provide all types of file and folder information. The other day I had a reason to revisit one of them and I spent a little time revising and expanding. This new function, Get-Extension will search a given folder and create a custom object for each file extension showing the total number of files, the total size, the average size, the maximum size and the largest size. At it’s core, the function takes output from Get-ChildItem and pipes it to Measure-Object. But I’ve incorporated features such as filtering and the ability to run the entire function as a background job.

By default, the function searches the top level of your $ENV:Temp folder and returns a custom object for each file type.

Here’s how this works.

The function uses a few parameters from Get-ChildItem, like -Include, -Exclude and -Force. If you use one of the filtering parameters, then you also need to use -Recurse. You can specify it, or the function will automatically enable it if it detects -Include or -Exclude.

Obviously (I hope), this only works on the file system. But I went ahead and added some code to verify that the specified path is from the FileSystem provider.

Normally, I’m not a big fan of Return. But in this situation it is exactly what I want since I want to terminate the pipeline. I could have also thrown an exception here but decided not to get that wild. Assuming the path is valid, the function builds a command string based on the specified parameters.

The function will invoke this string using Invoke-Expression and filter out any folders since all I care about are files.

The results are then grouped using Group-Object. Each extension group is piped to Measure-Object to calculate the statistics based on the file’s length property.

Lastly, the function creates a custom object representing each file extension using the New-Object cmdlet.

Because I’m writing an object tot he pipeline you can further sort, filter, export or whatever. This is what makes PowerShell so flexible and valuable to IT Pros.

One thing I quickly realized, was that scanning a large folder such as Documents folder or a file share UNC, could take a long time. I could use Start-Job with my original function, but it was a bit awkward. So I decided to include -AsJob as a parameter and move the job command into the function itself. This works because I take the entire core command and wrap it in a script block.

Because of scope the scriptblock needs parameters so I can pass it my command string and the Path variable which are used within the scriptblock. After $sb has been defined, if -AsJob was specified, the function uses Start-Job to create a background job. Otherwise, it uses Invoke-Command to execute it interactively.

Use the normal job cmdlets to get the results and manage the job. But now I can run something like this:

As always I hope you’ll let me know how this works for you. The complete script has comment based help and an optional line to uncomment at the end to create an alias for the function.

Download Get-Extension.

Get WMI Namespace

PowerShell and WMI just seem to go together like peanut butter and jelly, beer and pretzels, or salt and pepper. However, discovering things about WMI isn’t always so easy. There are plenty of tools and scripts that will help you uncover WMI goodness, but here’s another one anyway. Today’s PowerShell function will get all namespaces on a computer. Continue reading