Last Update: Sep 04, 2024 | Published: Feb 10, 2016
A little while back a discussion came up on Twitter about identifying commands with duplicate names. Part of the discussion related to the concept of command precedence. For example, there’s a cmdlet called Get-Process. But what if you also have a function called Get-Process? Which command gets called? PowerShell has a process of command precedence, which you can read about in more detail in About_Command_Precedence.
Here’s the short version, assuming you aren’t using a fully qualified path or file name.
In my Get-Process example, this means the function gets invoked first.
If I had an alias of Get-Process, then that would be invoked first.
But how can you identify potential conflicts? You can use Get-Command.
Interesting. That only showed the alias. You need to tell PowerShell to find all command types with a name of “Get-Process”.
Now I can see that there might a problem. If you want to be a bit more pro-active, you could manually search for potential naming conflicts.
get-command -CommandType function,cmdlet,alias | Sort Name | Out-GridView
I’ve highlighted a potential issue. If I rely on PowerShell to autoload the module when I run Add-ChildControl, it might not be from the module that I’m expecting. I either need to specify the full command name, which includes the module name:
help wpkadd-childcontrol
Or manually import the module first.
Another option, since I am concerned about duplicate names is to get all commands and group them on their name property.
$cmds = get-command -CommandType function,cmdlet,alias | group Name
Many commands will only be listed once. The $cmds variable is a GroupInfo object, which has a Count property. Here’s a sample.
$cmds | sort count -Descending | select -first 3
Wow. There are eight different versions of Add-EventHandler? Get-Command only shows one.
Maybe I need to look at the grouped results.
As the saying goes, “Knowing is half the battle.”
Let’s revise the expression and focus on those commands with more than one copy of the same name.
$dupes = get-command -CommandType function,cmdlet,alias | group Name | where {$_.count -gt 1} | Sort count –Descending
Here’s a sampling of the results.
With this data I can drill down and identify potentially problematic modules.
$dupes.group | group source | sort count -Descending
The group property will give me all of the commands, which I can then regroup on their source property and finally sort on the count property.
If any of these modules are mine, I might want to consider going back and revising command names to avoid duplicates. Or knowing the potential for conflicts ahead of time, I might want to import the module with a prefix.
import-module PowerShellPack -Prefix pp
Now all of the commands in the PowerShellPack module have a noun prefix of pp.
Use these names to invoke the command.
Or you may want to discover what type of commands are getting duplicated.
I have to say I was surprised to find so many duplicate command names. Personally, I rarely have run into an issue with a naming collision or invoking a command from a different module. But now I know what to look out for and as I build my own PowerShell solutions, I have commands I can run to test potential command names to avoid future problems.
Have you run into a problem with naming collisions or running a different command than you expected? Do you have a command naming strategy? I hope you’ll share you experiences in the comments.