Cmdlet clashes

Home  >>  Cmdlets  >>  Cmdlet clashes

Cmdlet clashes

On March 6, 2007, Posted by , In Cmdlets,Grrr,Hint,PowerShell,Rant, With 6 Comments

One of the things that struck me whilst developing Grrr as a snapin is: what do you do when you have a cmdlet with the same verb-noun pair as an existing cmdlet?

If someone else had a cmdlet called, say, out-banner, and that cmdlet was already loaded in a snap-in (perhaps mandated by site policy), would I be able to register and add the Grrr snapin, which also defines it?

I’ve scanned the available documentation and the language grammar, used introspection in the shell and so on, but could not find anything to deal with this problem.

With projects like PowerShell Community Extensions seemingly laying claim to hundreds of common nouns and verbs, I was concerned that the scope for writing unique cmdlets would dry up real fast.

To determine what would happen, I registered and added Soapyfrog.Grrr, then wrote a new snapin, Soapyfrog.Conflict, with a single cmdlet, out-banner, conflicting with the one in Grrr.

I registered and added this, and was surprised that no warning of a conflict was given. To see if both were added, I tried this:

PS> get-command out-banner

CommandType     Name                        Definition
-----------     ----                        ----------
Cmdlet          Out-Banner                  Out-Banner [-Text] <Str...
Cmdlet          Out-Banner                  Out-Banner [-Text] <Str...

Interesting. Both are available, so what happens when I try to invoke it?

PS> out-banner hello
The term 'out-banner' resolved to a cmdlet name that is ambiguous. Pos
sible matches include: Soapyfrog.Grrr\Out-Banner soapyfrog.conflict\Ou
t-Banner.
At line:1 char:11
+ out-banner  <<<< hello

OK, so at this point, we know it’s possible to break existing PowerShell scripts by simply registering and adding a new snapin with a same-named cmdlet. Not good. Is there a work-around?

PS> Soapyfrog.Grrr\out-banner hello -fg 'o'
o   o ooooo o     o      ooo
o   o o     o     o     o   o
ooooo ooo   o     o     o   o
o   o o     o     o     o   o
o   o ooooo ooooo ooooo  ooo

Yes! We can fully qualify the cmdlet name with the snapin name and a backslash.

So, it’s not as bad as I first feared, but as I noted above, you need to be very careful about how you code and run scripts in environments where you can’t predict what snapins are registered and installed.

I suppose you can create the correct shell environment with Export-Console and run your script with:

powershell -psconsolefile xxx.psc1 -noprofile -command myscript.ps1

Or if your script requires a snapin, add the snapin in the script and fully qualify each cmdlet you use.

6 Comments so far:

  1. I wonder if there is a way to define a permanent (in your profile) precedence for such ambiguous terms, so that if I use “out-banner” in my scripts, it will automatically assume that I am talking about the SoapyFrom.Grrr\out-banner.

  2. adrian says:

    I suppose you could resolve it like this:

    New-Alias out-banner soapyfrog.grrr\out-banner

    If you have lots of cmdlets, you might try this:

    gcm -PSSnapin soapyfrog.grrr |% {$n=$_.name;$s=$_.pssnapin; new-alias -name “$n” -value “$s\$n” }

    But that’s a bit of a hack.

    I notice that default tab completion in the shell does alternate between different same-named cmdlets, so the PowerShell team did at least think about this.

  3. Keith Hill says:

    You make a good point. It is something the PowerShell is probably going to need to address in a future release as more and more vendors provide PowerShell snapins.

  4. Well I suppose add-pssnapin sets its own precedence level, so if I add your snap-in most recently, it will be the default used in case of a conflict (I think). Anything more fine-tuned than that would probably just be annoying.

  5. adrian says:

    Unfortunately not. If there is a conflict, PowerShell throws a terminating error, eg:

    The term ‘out-banner’ resolved to a cmdlet name that is ambiguous. Pos
    sible matches include: Soapyfrog.Grrr\Out-Banner soapyfrog.conflict\Ou
    t-Banner.
    At line:1 char:11
    + out-banner <<<< hello

    So without qualification, having duplicates will break a script.

  6. alex says:

    hi nice site.