June 14th, 2015

Weekend Scripter: Deciphering Windows PowerShell Shorthand

Doctor Scripto
Scripter

Summary: Learn how to decipher Windows PowerShell shorthand notation in this guest post written by Tim Warner.

Microsoft Scripting Guy, Ed Wilson, is here. Welcome a new guest blogger today, Timothy Warner. Tim is an author and evangelist for Pluralsight, a premier online IT pro and development training company. Tim is the author of Sams Teach Yourself Windows PowerShell in 24 Hours, a contributor at PowerShell.org, and a member of the Nashville PowerShell User Group.

Hi everyone.

When I attended the Microsoft Ignite Conference in Chicago last week, I was somewhat surprised by the amount of Windows PowerShell shorthand I saw during product and technology demonstrations.

After all, doesn't The Community Book of PowerShell Practices tell us to confine our alias and positional parameter use to our ad-hoc console code? When we're sharing scripts with others, we should use formal cmdlet names and named parameters.

As a technical trainer, I was especially sensitive to the baffled faces I saw in those Ignite session audiences. Admittedly, these IT professionals in all likelihood have yet to board the Windows PowerShell train. In this blog post, I'll share three simple ways to translate terse Windows PowerShell code into a more formal, shareable format. Let's get started!

Method #1: Use Get-Alias

As our case study example, consider the following Windows PowerShell pipeline:

ps | ? { $_.CPU -gt 100 } | select ProcessName, CPU | sort CPU -des | ft -a

Sure, if you're already comfortable with Windows PowerShell and/or you have familiarity with Linux, you understand what's going on here. But put yourself in the shoes of the newcomer for a minute. What the heck does all that gobbledygook mean?

   Note  This pipeline shows all processes that have used over 100 seconds of processor time. We pare down our output
   by selecting only the ProcessName and CPU properties, sorting by CPU in descending order, and showing a data table
   with automatically sized column widths.

Enter the Get-Alias core cmdlet. If you haven't already done so, fire up an elevated Windows PowerShell console session and inspect the command Help:

Get-Help -Name Get-Alias -ShowWindow

Pay attention to two parameters in particular. The -Name parameter specifies the name of the alias, and the -Definition parameter maps to the associated Windows PowerShell command. Thus, we can do the following to resolve ps to its associated cmdlet:

Get-Alias -Name ps

   Note  You may run into problems if you're researching a custom alias that others defined on their computers. We're
   concerned only with default, built-in aliases.

Did you try it? The output tells you that ps is an alias that maps to Get-Process. This is logical for *NIX users who are accustomed to using ps to view running processes on their systems.

Let's use the same Get-Alias method to resolve the other aliases in our example pipeline:

Get-Alias -Name ?

Get-Alias -Name select

Get-Alias -Name sort

Get-Alias -Name ft

Do you know what -gt means? That is simply a comparison operator for "greater than." Please read the conceptual Help, about_comparison_operators, for more information.

Besides the abundance of aliases, the other "sticky wicket" in our sample pipeline is its liberal use of positional parameters. For instance, take a look at this pipeline section:

select processname, CPU

The previous statement works because if you look at the Select-Object Help, you'll learn that the position 1 parameter is -Property:

PS C:\> Get-Help -Name Select-Object -Parameter Property

-Property <Object[]>

    Specifies the properties to select. Wildcards are permitted.

    The value of the Property parameter can be a new calculated property. To

    create a calculated, property, use a hash table. Valid keys are:

    — Name (or Label) <string>

    — Expression <string> or <script block>

    Required?                    false

    Position?                    1

    Default value

    Accept pipeline input?       false

    Accept wildcard characters?  true

Please be courteous to your audience and always use named parameters in your shareable Windows PowerShell code! For instance, I would refactor this Select-Object statement in the following way:

Select-Object -Property ProcessName, CPU

Method #2: Use the Script Analyzer

If you're using Windows PowerShell 5.0 Preview, we can use the built-in PowerShell Script Analyzer module to help us resolve those pesky aliases.

The Script Analyzer is a flexible platform for static code analysis. The module's default ruleset was created by the PowerShell.org community as the result of a heated brainstorming session regarding Windows PowerShell best practices.

For grins, I added our case study pipeline to a script named testscript.ps1 stored in the root of my D: drive. Let's point the Script Analyzer at the one-line script and see what happens:

Invoke-ScriptAnalyzer -Path 'D:\TestScript.ps1'

The following image shows a bit of my output:

Image of menu

As you can see, the Script Analyzer output flags the use of aliases and the use of positional parameters, among many other code aspects. The output also notifies you which lines in your script contain rule violations.

Method #3: Use ISESteroids

Dr. Tobias Weltner gave us ISESteroids as a way to inject Windows PowerShell best practices "automagically" into our scripts by means of refactoring logic. ISESteroids (as you may already know) is a commercial add-on to the good ol' Windows PowerShell Integrated Scripting Environment (ISE).

We'll begin by downloading and updating the add-on in Windows PowerShell 5.0 Preview:

Install-Module -Name ISESteroids -Force

Update-Module -Name ISESteroids -Force

Now open an administrative Windows PowerShell ISE session and load the add-in from the ISE console:

Start-Steroids

This tool is awesome! Take a look at the following image, in which you can see the ToolTip Help in addition to an instant refactor button that will instantly convert your aliases to full cmdlet names:

Image of menu

To address positional parameters, click the refactor button, navigate to the Advanced pane in the Add-in window, expand the Command section, find CommandPositionalParameter, and click Apply.

Boom! All your parameters are named now. I show you all this in the following image:

Image of command output

To sweep up the shavings…

Remember that you need to provide only enough characters for Windows PowerShell to identify a switch parameter. Thus, in our sample code, you could expand -des to -Descending and -a to -AutoSize if you want to.

Of course, we also have Tab completion! If you've never used it, try typing format-t, pressing Tab, and typing -a followed by another Tab.

I hope you found this post helpful. At the very least, I hope I reminded you of the critical importance of "spelling out" every last bit of our Windows PowerShell code if it's intended for public consumption. Take care, and "Happy PowerShelling"!

~Tim

Thanks, Tim!

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Author

The "Scripting Guys" is a historical title passed from scripter to scripter. The current revision has morphed into our good friend Doctor Scripto who has been with us since the very beginning.

0 comments

Discussion are closed.