CMDLet Design Suggestion
I wanted to make a case for using Task Base CMDLETs instead of methods when designing Snapins. There have been several “Vendors” that have done CMDLets for Powershell: Exchange, Citrix, VMWare, and IBM to name a few. Most have done very well here, but this is one thing I think the VMware team excelled at.
< sidebar >
As some of you may know, I have a long background in Active Directory. As an Ex-Microsoft Support Professional in the Directory Services Team and later a Rapid Response Engineer specializing in Active Directory, let’s just say I have passion for all things AD.
I was lucky enough to spend a significant amount of time with the DS team at MS responsible for the Powershell CMDLets they will release at some time in the future. While I cannot give any details I can say… OMG! I CANNOT WAIT to be able to talk about them.
< / sidebar >
Here is the basic Goal
-
Get-Something | Filter | Change-Something | Change-SomethingElse | Save-Something
The thing to avoid: Depending on methods for object task.
Get-Something | %{$_.DoSomething()}
Here is an Example of what I mean
Lets say we have a Car Object (class). The Car object has Properties like Make, Model, Color, TireCount, Size, and Type.
We also have things we can do with a car like start , turn off, stop, turn, load, and unload.
We could approach this by creating a Car class with the set properties and methods. This may seem simpler, but it is not intuitive for your typical Admin. Your typical admin does not want to do this
-
Get-Car | ?{$_.Type -eq "MiniVan"} | %{$_.LoadPeople()} | %{$_.Start()} | %{$_.Turn("Right")} | %{$_.Stop()} | %{$_.UnLoadPeople()}
Ideally from an Admin perspective a bunch of Task oriented CMDLets would be your best bet. Let’s assume you had these CMDLets instead of Methods:
Get-Car
New-Car
Remove-Car
Start-Car
Stop-Car
Invoke-TurnCar
Invoke-LoadCar
Invoke-UnLoadCar
Set-Car
Your admin can now do this
-
Get-Car | ?{$_.Type -eq "MiniVan"} | Invoke-LoadCar | Start-Car | Invoke-TurnCar -Right | Stop-Car | Invoke-UnloadCar
This reads more like a sentence than a script syntax.
tshell :: Apr.28.2008 :: All, Powershell, Scripting :: 2 Comments »

Amazing, I was pondering just this issue today, and I have to disagree. Creating a cmdlet for every object and verb clutters the single flat cmdlet namespace terribly. If we truly made all methods cmdlets, we would be writing things like Get-Car | Get-Type $_ | Evaluate-Equality “MiniVan”… etc. Using methods provides a natural namespace scoped to the class of the object itself. It’s why OO languages are so much more manageable than, say, old-school Fortran or Cobol where there is a single global namespace for all functions.
I think the reason that admins might find the cmdlet syntax more “intuitive” (nothing in computers is literally intuitive… maybe consistent or predictable is a better word) is that the PS syntax for invoking a method on the current pipeline object is so arcane. Is it really %{$_.DoSomething()}? Yecchhh. I’m no PS guru, but if $_.Property is reasonable,I don’t see the problem with $_.DoSomething().
-gil
I have to side with Brandon on this one. I can certainly understand where gil is coming from, but during the training and feeding of a lot of Powershell newbies on the VMware Toolkit forum, I can say for sure that usability-wise this will please more admins. The funny thing for me is that just last night I was working on a chapter devoted to this very subject in my book. The section heading is “how to build a good pipeline”, and in it I make the case that most of the “power” in PowerShell is seen when you use streaming pipelined operations with cmdlets.
-hal
Co-host, PowerScripting Podcast (http://powerscripting.net)