How to check if a cmdlet exists in PowerShell at runtime via script

PowershellPowershell 2.0

Powershell Problem Overview


I have a PowerShell script that needs to run under multiple hosts (PowerGUI, PowerShell ISE, etc...), but I am having an issue where sometimes a cmdlet doesn't exist under one of the hosts. Is there a way to check to see if a cmdlet exists so that I can wrap the code in an if block and do something else when it does not exist?

I know I could use the $host.name to section the code that is suppose to run on each host, but I would prefer to use Feature Detection instead in case the cmdlet ever gets added in the future.

I also could use a try/catch block, but since it runs in managed code I assume there is away to detect if a cmdlet is installed via code.

Powershell Solutions


Solution 1 - Powershell

Use the Get-Command cmdlet to test for the existence of a cmdlet:

if (Get-Command $cmdName -errorAction SilentlyContinue)
{
    "$cmdName exists"
}

And if you want to ensure it is a cmdlet (and not an exe or function or script) use the -CommandType parameter e.g -CommandType Cmdlet

Solution 2 - Powershell

This is a simple function to do what you're like to do :)

function Check-Command($cmdname)
{
    return [bool](Get-Command -Name $cmdname -ErrorAction SilentlyContinue)
}

How to use (for example):

if (Check-Command -cmdname 'Invoke-WebRequest')
{
     Invoke-WebRequest $link -OutFile $destination
}
else
{
     $webclient.DownloadFile($link, $destination)
}

Solution 3 - Powershell

If the command is in Verb-Noun form then you can use Get-Command with Verb and Noun parameters.

# Usage:
if (Get-Command -Verb Invoke -Noun MyCommand) {
  # cmdlet Invoke-MyCommand exists
}

Get-Command -Verb Get -Noun Item

# Output:
# CommandType     Name                  Version    Source
# -----------     ----                  -------    ------
# Cmdlet          Get-Item              7.0.0.0    #Microsoft.PowerShell.Management
Get-Command -Verb Take -Noun One

# No output.
function Take-One { [CmdletBinding()]param() }
Get-Command -Verb Take -Noun One

# Output:
# CommandType     Name                   Version    Source
# -----------     ----                   -------    ------
# Function        Take-One

Tested on Windows PowerShell 5.1 and PowerShell Core 7.0.

Edit 2020-11-09 Additional example. Also usage example (adapted from Keith Hill answer).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGreg BrayView Question on Stackoverflow
Solution 1 - PowershellKeith HillView Answer on Stackoverflow
Solution 2 - PowershellAlexander SchüßlerView Answer on Stackoverflow
Solution 3 - PowershellernestasjuView Answer on Stackoverflow