Automating the world one-liner at a time…
We like to say that PowerShell uses Verb-Noun naming. If we were accurate, we would say that PowerShell uses Verb-PrefixNoun naming. For instance: Get-WinEvent . WIN is a prefix for Windows. Every now and again people look at this and ask “what's up with command prefixes ?!?”. Actually, the question usually comes from teams that are implementing Cmdlets and don't understand why they have to use prefixes. They sometimes feel like their noun is unique or they want to own the noun or they think they may get reorganized into a different group so they are not sure what a good prefix would be (hey - is a legitimate issue for some teams – it just has nothing to do with the customer.)
Prefixes mitigate naming collisions.
Consider the case of the recent cmdlet Get-WinEvent which was developed by the Windows Diagnostics team (the same great team that brought you the super awesome W7 troubleshooting [which uses PowerShell heavily]). What would've happened if they'd just called it Get-Event. The PowerShell team needed to use the name Get-Event Cmdlet (I'll explain why it doesn't use a prefix later) so without a prefix these two Cmdlet names would collide. So what happens with a collision? Well one wins and the other loses. Specifically, last writer wins. So if you had a script that uses Get-Event, it is going to use would ever last defined that name. In other words your script will break.
(NOTE: For the record – the story is much more complicated that that. The Diag team used the name “Get-Event” first and we OKed it with them and then sometime later we got crisp about our policy for when PowerShell needs to own generic nouns and made them change it. It was an unfortunate situation and the diag team ended up “taking one for the team” and doing a bunch of extra work so that we could deliver a great customer experience. We all owe them a big THANK YOU.)
No matter what we do, naming collisions will occur so let's talk about how you deal with that when it happens. The solution is simple, you use the full Cmdlet name. Full Cmdlet name? Yes that's right, every Cmdlet that has a short and a full name. The names you use all day long are the short Cmdlet names. The full name Get-WinEvent is Microsoft.PowerShell.Commands.Diagnostics\Get-WinEvent. That’s right, if anyone comes along and collides with Get-WinEvent, you just go change all your scripts to use Microsoft.PowerShell.Commands.Diagnostics\Get-WinEvent. OUCH! Clearly this is an undesirable situation but at the end of the day these things happen so you have to have a solution. That said, it should be obvious why we want to avoid collisions as much as possible.
Think through the problem.
When we thought through this problem we made some guesses about how many things needed to be named. It's been many years since we had the discussion but I believe the numbers were something like this:
The key observation here was that we had to minimize the possibility of short names colliding on a particular machine (not a customer site or the industry).
Verb names are meant to be standard so they're always going to collide - that's a good thing (because it means you can guess which you want to do in your guess will be correct). So this is really an issue of increasing the Hamming Distance of noun names. Adding a 2-4 character prefix (indicating the team or product that owns the noun) in front of the noun solves this problem.
NOTE: The side benefit of using prefixes is that it provides an easy way to find all the commands from a particular source. For instance, the Active Directory team chose the prefix “AD” so you can type: Get-Command *-AD* to find all their Cmdlets.
So that is the reason why we are hardcore on the guidance to use prefixes in front of your noun names.
Oh wait, I promised to tell you why PowerShell sometimes doesn't use the prefix PS in its Cmdlets. There are three reasons for this:
But I hope this clarifies the importance of prefixing. As a community it is in your best interest to enforce this standard quite getting grief to those teams and companies that don't adhere to it.
Jeffrey Snover [MSFT] Distinguished Engineer Visit the Windows PowerShell Team blog at: http://blogs.msdn.com/PowerShell Visit the Windows PowerShell ScriptCenter at: http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx
we have a complete network and applications testing framework written currently in v1 (now porting to v2) and we have always used a prefix. our company name is Front Porch so we use the FP in front of the noun for most cmdlet/function names unless it is specific to a product application then we use a Three Letter Acronym to identify the product the command is targeted to. Prefixes are awesome and we need more of them so people can see were the command comes from!
It would be good if the prefixes were all consistent with the .dll / snapin. When you get multiple snapins loaded and potentially hundreds of cmdlets available in a session it would make tab-completion much easier. For instance, if all the Exchange cmdlets were prefixed with 'ex' it would speed up tabbing through a list of cmdlets if you don't remember the exact name, but know it's Exchange specific (eg get-user should have been get-exuser).
I would have loved to see an aliasing capability for extremely long module names e.g. Set-ModuleAlias psdiag Microsoft.PowerShell.Commands.Diagnostics
Then you would disambiguate Get-WinEvent simply as psdiag\Get-WinEvent. The benefit is that you don't create a new namespace i.e. the prefixed nouns of a module. Rather, your just creating a convenient alias for an existing namespace - the module name.