Summary: Learn how to handle naming conflicts for Windows PowerShell cmdlets.

Hey, Scripting Guy! Question Hey, Scripting Guy! My Windows PowerShell installation is completely hosted on my laptop. In fact, I tried to uninstall and reinstall Windows PowerShell, but that did not work. I really do not want to have to pave my laptop. I download this module from the Internet. It works really well, but the issue is that one of the cmdlets replaced one of the standard cmdlets on my computer. I really need to be able to use the standard cmdlet, and I do not know what to do. Help!

—DV

Hey, Scripting Guy! Answer Hello DV,

Microsoft Scripting Guy, Ed Wilson, is here. This morning I am sitting at my desk sipping a cup of English Breakfast tea with a bit of licorice root, peppermint herb, spearmint herb, and a cinnamon stick. It is quite refreshing, and delightful—especially because my arms feel like they are made from rubber. I just got back from the gym. (It is difficult to replace years of bad habits with a few weekly sessions at the gym, but it is also import to get started—and that is what I am doing.)

PowerShell cmdlet naming conflicts

Windows PowerShell is powerful and easy-to-use. It makes a lot of decisions for me. For example, if I import a module that has a cmdlet with the same name as an existing cmdlet, Windows PowerShell will use the new cmdlet. For example, let's say that I import a module named Process. It has a function named Get-Process. When I type Get-Process, I get the results from that function. This is shown here:

Image of command output

From this display, I see that I am not getting the normal output from the Get-Process cmdlet that I have used since Windows PowerShell 1.0 came out. This is disappointing. So I use the Get-Command cmdlet to see what is going on. Here are the results:

PS C:\> Get-Command -Module Process

CommandType     Name                                               ModuleName

-----------     ----                                               ----------

Function        Get-Process                                        Process

It seems that Get-Process has been replaced by a function with the same name. It is from a module named Process.

I can unload that module by using the Remove-Module cmdlet as shown here:

Remove-Module Process

   Note  Using Remove-Module only unloads the module from memory. It does not actually delete the module, nor does
   it remove it from disk.

Now if I use the Get-Process cmdlet, I see the standard output. This is shown here:

Image of command output

But what if I want the commands that are available from the Process module? How can I have access to those commands, and also access the standard Get-Process cmdlet? There are actually two ways to coexist...

Two ways to coexist

The first way to coexist (but by no means the easiest) is to reference the cmdlet by its complete name. This is the name of the module, separated by a backslash, and then the cmdlet name. To determine the cmdlet’s module, use the Get-Command cmdlet. Here is an example:

PS C:\> Get-Command Get-Process | ft -AutoSize

CommandType Name        ModuleName

----------- ----        ----------

Cmdlet      Get-Process Microsoft.PowerShell.Management

I see that the Get-Process cmdlet is in the Microsoft.PowerShell.Management module, so this is what I will need to type.

I import the Process module, check to ensure that the Get-Process cmdlet is overwritten, and then specify the complete name. It works:

PS C:\> Import-Module Process

PS C:\> Get-Process | select -Last 1

splwow64.exe

PS C:\> Microsoft.PowerShell.Management\Get-Process | select -Last 1

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName

-------  ------    -----      ----- -----   ------     -- -----------

   1630     142   112116     154792   530    10.41   7044 WWAHost

   Note  Tab expansion does not work for module names when you are specifying the complete name. So it is helpful to
   copy the module name to the Clipboard when looking it up via Get-Command.

The second way to coexist is to specify a command prefix when you import the module. This will add a couple of letters to the noun name; therefore, it avoids the naming conflict. Here is an example:

First I import the module, and specify the prefix. Then I use Get-Command to see the cmdlet name, and I use the new cmdlet name (Get-edProcess) to retrieve a single process name. This is shown here:

PS C:\> Import-Module Process -Prefix ed

PS C:\> Get-Command -Module process

CommandType     Name                                               ModuleName

-----------     ----                                               ----------

Function        Get-edProcess                                      Process

PS C:\> Get-edProcess | select -Last 1

splwow64.exe

Now I can use the standard cmdlet with the standard cmdlet name. Here, I retrieve a single process object:

PS C:\> Get-Process | select -Last 1

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName

-------  ------    -----      ----- -----   ------     -- -----------

   1630     142   112116     154304   530    10.41   7044 WWAHost

DV, that is all there is to handling Windows PowerShell naming conflicts. Join me tomorrow when I will talk about the Windows PowerShell Summit in Amsterdam.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy