PowerShell Command Precedence

2017/06/30 | 2 minute read |

Assuming the following scenario:

  • I’m declaring a module MyModule with one function called Get-Process which returns the following text: Module
  • I’m also declaring a function in my session called Get-Process which returns the following text: Function
  • And we know there is also a built-in Cmdlet called Get-Process which returns the list of processes running on my machine

If I call Get-Process which result will I see ?

Code

# MODULE
#  declare a very basic module and save to mymodule.psm1 file
@"
    function Get-Process {
        "Module"
    }

    Export-ModuleMember -Function Get-Process
"@ | Out-File mymodule.psm1 -force
#  load the module and its function
Import-Module .\mymodule.psm1


# FUNCTION
#  declare a function in my session
function Get-Process {
    "Function"
}


Calling Get-Process

Now if I run the following which output will I see ?

# Which one will be called ?
Get-Process

Output:


Function

Why ? because the function declared in my session take precedence over the module and the cmdlets.

Windows PowerShell uses the following precedence order when it runs commands:

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


Qualified name

Well what if I don’t want to change anything to my script, how can i launch the Get-Process function from the module mymodule.psm1 ?

By using the Qualified name <Module>\<function>

MyModule\Get-Process

Same if you want to call the built-in Cmdlet Get-Process, you specify the module

Microsoft.PowerShell.Management\Get-Process


What about functions ? You can’t use qualified name for functions declared in the session

Retrieving the module name

But wait, how did you know the exact module name ?

You can use Get-Command to retrieve all the Command with the name Get-Process by using the parameter -All

Get-Command Get-Process -all

Output:

CommandType  Name         Version  Source                         
-----------  ----         -------  ------                         
Function     Get-Process                                        
Cmdlet       Get-Process  3.1.0.0  Microsoft.PowerShell.Management
Function     Get-Process  0.0      mymodule                       

Then you can use -CommandType to specify the Cmdlet type and select the property ModuleName. (You’ll find also the same information in the properties Source and Module)

(get-command Get-Process -CommandType Cmdlet).ModuleName

Output:

Microsoft.PowerShell.Management


Module Prefix

One technique to prevent name conflict with module is to use Import-Module with the parameter -Prefix.

For example:

Import-Module .\mymodule.psm1 -Prefix FX

This will add FX as a prefix of all the functions noun present in the module. In our case we only have one.

Get-FXProcess

Output:

Module


More information

You’ll find more information of this topic in the following link(s)

Leave a Comment