Tag Archives: Scripting

More PowerShell Toolmaking Fun

blacksmith I am having so much fun making my own PowerShell tools that I just can’t stop. I’ve been using my Get-Commandmetadata function that I wrote about a few weeks ago. A driving force in all of this is to have a toolset that I can use efficiently from the console. Or to put it in terms you might appreciate: the biggest bang for the least amount of typing. Today, I have another example. I took a common PowerShell expression and simplified it into its own command. And even though the final code looks like a lot, it didn’t take me very long because my toolmaking tool “wrote” most of the script for me.

So the common task is finding services that match a certain state such as running or stopped. You’ve most likely seen this expression:

Not the most onerous command to type, but even I have mistyped and had to correct. If this is a common task, why not create an easy to use tool?

Yes, I could have written my own function that called Get-Service, but then I’d have to write all of the code to accommodate all of the parameters for Get-Service. With the proxy command, all I need to do is insert my own code.

In other words, I let Get-Service do its thing and then filter the result. Now I can easily do this:

Or, because I’m typing this, I could use my own alias.

One thing I want to point out, is that for the new Status property, you’ll notice I didn’t cast it as a string.

I could have made it a string, but by using the actual enumeration, PowerShell will autocomplete possible values.
get-myservice

How did I know what to use? I used Get-Member.

It is really not that difficult or time consuming. I spent more time writing this blog post than I spent creating the function.

I hope this will inspire you to create your own PowerShell tools and that you will share the fruits of your labors.

Friday Fun – A Popup Alternative

windowpane-thumbnail In the past I’ve written and presented about different ways to add graphical elements to your PowerShell scripts that don’t rely on Windows Forms or WPF. There’s nothing wrong with those techniques, but they certainly require some expertise and depending on your situation may be overkill. So let’s have some fun today and see how you can display a popup message in a graphical form, using something you already know how to use.

It may not be sexy, but how about using Notepad. Here’s how. First, you need some content to display. Using a here string is good approach as it makes it easy to create a multi-line block of text.

With a here string you could also insert variables.

Next, create a temporary file with the text.

To display the message all you need to do is run Notepad.

This will return your PowerShell prompt but you want to make the popup more integral to your script, in which case I’d suggest using Start-Process.

The major advantage is that when you close Notepad your script continues so you can then delete the temp file. While we’re mentioning the temp file, if you tried my demo you’ll notice that the file name is displayed in the title bar. There’s no requirement that your file have an extension.

Notice my use of Join-Path to create a file name. I suggest you use this cmdlet instead of trying to concatenate pieces together. But now I get something a little nicer.

notepad-popup

With Notepad you could save the file elsewhere or even print it. I even created a re-usable function for you.

This function will automatically delete the temp file for you. If you have another text file viewer that you can launch from the command line you could use that instead of Notepad. As I mentioned at the beginning this is hardly exciting PowerShell but I hope you picked up something new and useful. Have a great weekend.

Creating Your Own PowerShell Command

atomic powershellLast week, I posted a PowerShell function that you could use as an accelerator to create your own PowerShell tools. My tool takes command metadata from an existing PowerShell cmdlet and gives you the structure to create your own tool wrapped around what is in essence a proxy function.

The advantage, besides saving a lot of typing, is that by using a proxy function you can take advantage of the wrapped cmdlet’s features and parameters. But perhaps it would help to see an example. With the Get-CommandMetadata function loaded into the PowerShell ISE, I run this command:

Instead of using CDXML, or writing my own function to call Get-Cimstance, I’m going to create a proxy to Get-Ciminstance that designed to retrieve operating system information. Here’s what I start with.

As with any PowerShell scripting project, you have to think about who will run your command and what expectations they might have. In my example, I simply want to be able to specify a computer name or a CIM Session and retrieve information from the Win32_Operatingsystem class. So to begin with I can delete all the parameter definitions except Computername and CIMSession. I’ll also keep the OperationTimeOut parameter just in case. As you can see in the code sample, Get-CimInstance also has a number of parameter sets. Again, I can delete references to ones I’m not going to use.

Here’s my revised parameter definition.

One change I made was to give the computername a default value for the local computer. I amd doing this so that the PSComputername property will always have a value.

But you may be wondering, what about the classname? This is where the fun begins. I am going to hard-code other parameters into the function.

When the wrapped command is executed it will use these values which is what I want. At this point, I could save the function and run it. But the output would be the same as if I had run Get-Ciminstance and I have a specific output in mind. Here’s how.

First, copy and paste a new version of the $scriptCmd line. Comment out the original line.

What I need to do is create my own script command, which must be a single pipelined expression.

I still want the wrapped Get-Ciminstance command to run but then I’m going to pipe the results to Select-Object and specify some custom properties. That is the extent of my major changes, although I also will add some additional Write-Verbose lines for tracing and troubleshooting. After updating comment based help, here’s my final command.

Now to test it out:

I can specify a computername:

Or use CIMSessions.

osreport

I didn’t have to write any code to use the CIMSessions. I let the wrapped cmdlet handle everything for me. The end result is that I now have a very complete PowerShell tool that didn’t take much time to create. I probably spent more time getting the comment-based help written than anything.

Hopefully this gives you an idea of how to take your PowerShell toolmaking to the next level.