Friday, January 09, 2009

More on PowerShell Best Practice

I read an very interesting post over on James O'Neill's blog. It was interesting  both because it talked PowerShell, but also because it talked about OCS and the neat PowerShell code James had written to support OCS 2007. 

As part of the Server 2008 Resource Kit, there’s a large script that contains a number of function definitions. If you dot source this script file, you can then use the functions sort of like cmdlets and administer OCS using PowerShell. I demo this script in my OCS Voice Ignite classes and the reaction is good!

When I first saw these cmdlets, my eyes lit up since it meant I could use these functions. However, I quickly noticed that some important best practices had not entirely been adhered to. Nothing major and certainly nothing that would break the functions – but it did not leverage PowerShell’s discoverability model.

In the latest post, James describes the re-write and the lessons he learned. The lessons are great ones that all PowerShell users should employ as they implement PowerShell into their environment. These are:

  • PowerShell nouns are written in the singular. So a cmdlet/function to get all users would be GET-USER not GET-USERS (even though the latter is more likely to be the result of the get).
  • Be consistent with Nouns, Avoid using “usage” in one function and “PhoneUsage” in another one.
  • Avoid creating new verbs. While adding verbs like LIST is tempting, using Get- is more discoverable.
  • Make use of the pipeline  when writing cmdlets. This enable a the user to pipe things into commands, pass an object or a name to fetch the object.
  • Assume users want to use wildcards and allow wherever possible.

These are great lessons we all should  learn. Personally, I have some trouble with the third one when writing scripts for my PowerShell Scripts Blog (

For those of you who will be buying the OCS 2007 R2 Resource Kit book (something I’ll sure be doing!), the function library is a real opportunity to do some repackaging using PowerShell V2 CTP. James’ .PS1 script contains none of the V2 stuff (Cmdlet binding and parameter attributes, auto-help contents, using manifests to do the updating of type data, etc).

No comments: