PowerShell Problem Solver: Finding Duplicate Commands

powershell-hero-img
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.

  1. Alias
  2. Function
  3. Cmdlet
  4. Native windows commands

In my Get-Process example, this means the function gets invoked first.

Testing command precedence (Image Credit: Jeff Hicks)
Testing command precedence (Image Credit: Jeff Hicks)

If I had an alias of Get-Process, then that would be invoked first.
More command precedence testing (Image Credit: Jeff Hicks)
More command precedence testing (Image Credit: Jeff Hicks)

But how can you identify potential conflicts? You can use Get-Command.
Getting a command (Image Credit: Jeff Hicks)
Getting a command (Image Credit: Jeff Hicks)

Interesting. That only showed the alias. You need to tell PowerShell to find all command types with a name of “Get-Process”.
Getting all versions of Get-Process (Image Credit: Jeff Hicks)
Getting all versions of Get-Process (Image Credit: Jeff Hicks)

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

Listing duplicate command names (Image Credit: Jeff Hicks)
Listing duplicate command names (Image Credit: Jeff Hicks)


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 wpk\add-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

Listing some duplicate command names (Image Credit: Jeff Hicks)
Listing some duplicate command names (Image Credit: Jeff Hicks)

Wow. There are eight different versions of Add-EventHandler? Get-Command only shows one.
Getting a command (Image Credit: Jeff Hicks)
Getting a command (Image Credit: Jeff Hicks)

Maybe I need to look at the grouped results.
Checking grouped results
Checking grouped results (Image Credit: Jeff Hicks)

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.

A sample of duplicate names (Image Credit: Jeff Hicks)
A sample of duplicate names (Image Credit: Jeff Hicks)

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.

Grouping duplicates by source (Image Credti: Jeff Hicks)
Grouping duplicates by source (Image Credti: Jeff Hicks)

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.

Viewing import commands with a prefix (Image Credit: Jeff Hicks)
Viewing import commands with a prefix (Image Credit: Jeff Hicks)

Use these names to invoke the command.
Testing prefixed commands (Image Credit: Jeff Hicks)
Testing prefixed commands (Image Credit: Jeff Hicks)

Or you may want to discover what type of commands are getting duplicated.
Grouping duplicate commands by type (Image Credit: Jeff Hicks)
Grouping duplicate commands by type (Image Credit: Jeff Hicks)

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.