PowerShell Problem Solver: An Advanced HotFix Reporting Tool


Over the course of several articles, we’ve been developing a PowerShell tool to provide hot fix information. The command is built around the Get-HotFix cmdlet but takes it a step further. If you are just jumping in, I encourage you go back to the beginning so you’ll understand how we got here.

Pipeline Input

From the previous article, the function can take multiple computer names, but they can’t be piped into the command like other cmdlets.  The solution is to create an advanced PowerShell function. To do that, the first change is that the body of the function needs three special scriptblocks: Begin, Process and End. The only one that is truly required is Process, but I always use all of them. In the Begin scriptblock, you put any commands you want to run before processing any pipelined values. In the End scriptblock, you put code to run after everything has been processed from the pipeline. The code in the Process scriptblock runs once for each computer.

In my function, I’ll move the code that creates the parameter hashtable into the Begin block.

I’ll talk about the Write-Verbose commands later.  The End block isn’t really necessary in this command.

The Process scriptblock has the majority of the code from the basic version of the function.

I can use the same parameter names for the pipelined input, which in this case is the computer name. But this means I need to tell PowerShell that the Computername parameter can take a value from the pipeline.

You can specify whether you want to accept any value (ValueFromPipeline) or accept any object that has a property name the same as the parameter name (ValueFromPipelinebyPropertyName). This would be useful if you were importing from a CSV file that had a Computername property. You could then pipe the imported objects to the command and PowerShell would take the property name and hook it up to the parameter. In PowerShell v3 you would have explicitly set the value settings to $True.

With these settings  I can now run commands like this:

Testing pipelined input
Testing pipelined input (Image Credit: Jeff Hicks)

$C is a collection of computer names that I can now pipe to the command. I could also have gotten the same result by running the command like this:

By the way, astute readers will notice that I changed PSComputername to Computername. I did this to make the command more compatible with other commands that might take Computername as a parameter via the pipeline.


The last step I usually take is to add elements that anticipate what silly things a user might do,  or something to make the command easier to use. For example, perhaps the Help Desk is used to using -Name or -CN instead of -Computername. I can add an alias to the parameter.

Now I can use any of these alternate parameter names, even on imported objects, as long as the property name matches the parameter or one of its aliases.

Getting data from imported objects
Getting data from imported objects (Image Credit: Jeff Hicks)

I also typically add this parameter validation element to parameters that I want to ensure have a value:

I could have made the Computername parameter Mandatory, but then I wouldn’t have been able to set a default value. Or I suppose I could have more closely mimicked the behavior of Get-HotFix. But I’ll stick with what I have for now.

The last element, which you saw earlier, was my use of Write-Verbose. I add these statements throughout the command to identify what is happening and often the state of key variables. Because I’m using [cmdletbinding()] in the function, I automatically get the -Verbose parameter. If someone runs the command with -Verbose, they will see all of the messages. Otherwise, they are ignored. This is very handy when debugging or troubleshooting. If someone is having a problem with the command, I can have them start a transcript, run the command with -Verbose, stop the transcript and send it to me for review. You can include as much Verbose output as you feel is necessary. Often the verbose messages can double as internal documentation!

Verbose output
Verbose output (Image Credit: Jeff Hicks)


And last, but by no means least, I create some comment-based help. At a minimum, I recommend defining the Synopsis, Description and at least one example.

Displaying help for the function
Displaying help for the function (Image Credit: Jeff Hicks)

The command now looks and behaves like any PowerShell  command. Here is my complete, advanced function.

I should probably use something like Git to maintain this as, more than likely, someone will come to me with a feature request. I’m not too concerned about bugs because I tested and developed slowly. I didn’t sit down and attempt to write the finished product all at once. This is something I strongly recommend to people just getting started with PowerShell scripting and toolmaking.  Start slow and small and increment features and complexity as you need and learn.

Next Steps

At this point, I’m quite happy with the finished result. If I was in a true corporate environment, I’d digitally sign the script and check it into source control. I might add this to a module to make it even easier to use and distribute. But the bottom line is that I can now use this command to get the hotfix information I need and process the results however I desire.

I hope you found this series educational and maybe even a little bit fun. Your comments are welcome and appreciated.

Related Topics:

  • PowerShell

    Don't have a login but want to join the conversation? Sign up for a Petri Account