ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
You have probably heard the story (or legend) about Pablo Picasso and his napkin drawing. A guy goes up to Picasso in a cafe and asks for an autograph or something. Picasso sketches out something in a minute or so. He turns to the guy and says, “That will be $10,000".” The guy is stunned and replies “It only took you a minute!”. To which Picasso replies, “Yes, but it took a lifetime of experience.”
By now you’re wondering what this has to do with Windows PowerShell. Well, the reason Picasso could create a masterpiece in minutes on a napkin was because he already knew all the rules and knew how to apply them in the most efficient manner possible. Because he already knew “the long way” to do something, he was able to take a “shortcut”. I’m simplifying a bit to make my PowerShell analogy so stick with me.
There are several reasons I’m bringing this up, but primarily I want to see PowerShell adopted and spread throughout the enterprise. What I’m afraid of is that new-comers will see somebody’s napkin-based PowerShell script and think that’s pretty easy only to find out it is a lot more difficult. You try copying a Picasso line drawing freehand.
Specifically, I’m referring to what I would like to see as a best practice regarding PowerShell writing and publishing. My first rule is to always use full cmdlet names and parameters in any PowerShell example. No aliases. Although there are a few exceptions which I’ll talk about in a moment. My reasoning for this rule is two-fold. First, if you are writing a production script, there is no performance penalty for using full cmdlet names and parameters. In fact, there is a minor performance hit when using aliases because PowerShell has to resolve the alias. Cmdlet and parameter names are long, but at least they are meaningful. And when you come back to a script in a year, or when your successor with very little PowerShell experience has to update it, having plain-PowerShell language makes this much easier.
Even if you are posting a PowerShell example that will be run at the command line, I encourage you to use full names. Again, some brand new to PowerShell will likely be a little frustrated trying to figure out what this means:
ps | ? {$_.ws -gt 10mb} | %{ $_.path} | select -unique | sort -des
But if you use the full PowerShell syntax, it’s a little easier to swallow.
get-process | Where-Object {$_.WorkingSet -gt 10MB} | ForEach-Object {Write-Output $_.path} | Select-Object -Unique | Sort-Object -Descending
Once someone acquires some PowerShell experience, they can use the shortcuts in the console. I’m all for that. If you are running PowerShell as an interactive management shell, then by all means take advantage of every PowerShell shortcut to save on typing. But when sharing PowerShell knowledge, the same is counter-productive. With features like tab completion this should hardly be a tedious task.
As I mentioned, I have a few exceptions about the no alias rule that really boil down to common sense. Given a modicum of Windows experience, don’t use any alias that isn’t plain English or beyond basic experience. Thus, I don’t have too much of a problem using DIR in an example. Yes, it is an alias for Get-ChildItem, but it is also such a common term that there’s no mystery. Compare that to aliases like gsv, clhy or nal. Yes, you can take the time to figure them out, but wouldn’t it be much easier to learn PowerShell with the full names of Get-Service, Clear-History, and New-Alias?
That said, if you need to use DIR with any number of parameters, then I would suggest using the full cmdlet name. A PowerShell example like this isn’t difficult to understand:
dir C:\temp
But as soon as you start increasing the complexity, the DIR command starts looking less like the DIR command an admin is familiar with it.
dir c:\temp -fi *.xml -for –rec
I’d rather see it expressed more completely.
get-childitem –path c:\temp –filter *.xml –force -recurse
My other concern regarding what I see in the community is the approach of PowerShell as a scripting language. Now don’t get me wrong. PowerShell as a scripting language and support for using .NET objects directly is incredible stuff. But again, I come back to the young admin trying to see what PowerShell is all about and they come across a complex PowerShell example importing .NET assemblies, invoking methods directly and generally rising (in my opinion) to the level of systems programming. That’s not what admins need to see and I’d argue it is next to impossible to learn PowerShell from such examples. If you publish these types of examples, all I ask is that you explain that this is high-level stuff that can’t be accomplished using standard PowerShell cmdlets.
Which brings me to the end of today’s art of PowerShell lesson. Windows PowerShell is an rich, object-based interactive management shell. You combine one or more commands in a pipelined expression and do something useful. For more complex or repetitive tasks you can take the same commands you would type at the PS prompt and put them in a plain text script file.
While I respect the many PowerShell Picassos in the community, and we’re fortunate to have them, keep in mind that very few people can pick up Windows PowerShell and create masterpieces on the back of a napkin. But they can take a clear and unambiguous example to learn from and over time discover what they can take away until they are left with pure PowerShell that is a work of art.
Hear, hear! It’s something I’ve been guilty enough of myself in the past. It reminds me of when I was first learning Perl, and had to sift through all of the “magic” variables and functions. The convenience the shortcuts provide doesn’t come close to making up for the hassle they provide everyone else (and sometimes even yourself, if it’s been long enough since you looked at a piece of code).
While I fully agree with first part (I use aliases only for backwards compatibility and of course DIR\CD :)), I don’t fully agree with second part (.NET).
If you meant it as “using assemblies, psbase etc” then I agree, however using .NET object properties\method can even improve reading of the code
http://www.out-web.net/?p=772
That’s exactly the type of .NET PowerShell code I was referring to. There’s nothing wrong, as long as the author explains this is high-level, not ordinary PowerShell.
True, aliases are great but can hinder the code readability. I wrote an Expand-Alias function that will resolve and replace aliases in your scripts, that way you don’t have to worry about leftover aliases sneaking by in you examples or scripts.
I use .Net static methods when there is no alternative in pure PowerShell, or the alternative is too lengthy or complex.
If you’d like to give Expand-Alias a try read my entry at http://robertrobelo.spaces.live.com/blog/cns!1D7FE2F4A61D31E1!243.entry I hope it helps you or your readers.
Great story. There’s one that mirrors it that I had to share. A woman calls a plumber and tells him her basement is flooding and she needs his services ASAP. He comes over, looks at a couple of pipes for a minute and surveys the scene, goes to his tool box, takes out some pipe-fitting pliers, tightens one pipe, then another and voila, the water stops gushing. The woman is utterly grateful and gushes joy. Then he gives her the bill. It’s for $1,000. She genuflects telling him it’s too way expensive and wants him to itemize it. He does. It says, “Tightening the pipes, $1.00. Knowing what to do and where to tighten, $999.”
Glenn Ryan
Ok Pablo,
You call your blog “The Lonely Administrator”. Is this because you are related to Herb Alpert?
I am an old trumpet player, that is true.
On the serious side.
Since reading this blog entry I have started ot go back to using full CmdLet names in examples I post because I agree with you. Thse learning PowerShell should not have to work to understand all of the time.
There is a blogger who recently called for the use of more aliases as if 200+ is not enough. The cahnce of an alias becoming hijacked is very possible so published code should avoid alias usage for safety.
I once saw a post of a bit of code that would expand all aliases before publication. Can’t find it now.
Look back through the comments. I think there’s a link to the script you’re talking about.
Love The Tijuana Brass. I saw Herbon PBS a couple of weeks ago.
I used ot work with a Sax/Piano player that I hired as aprogrammer. He was excellent. Musicians make better…scripters?!?