Gain Remote Access to the Get-ExCommand Exchange Command

Summary: Learn how to gain access to the Get-ExCommand Exchange command while in an implicit remote Windows PowerShell session.

Hey, Scripting Guy! Question Hey, Scripting Guy! I liked your idea about connecting remotely to Windows PowerShell on an Exchange Server. The problem is that I do not know all of the cmdlet names. When I am using RDP to connect to the Exchange server, there is a cmdlet named Get-ExCommand that I can use to find what I need. But when I use your technique of using Windows PowerShell remoting to connect to the Exchange Server, for some reason Get-ExCommand cmdlet does not work. Am I doing something wrong? Please help.  


Hey, Scripting Guy! Answer Hello JM,

Microsoft Scripting Guy, Ed Wilson, is here. Well, it looks like my colleagues in Seattle are starting to dig out from the major snowstorm they received last week. Here in Charlotte, it has been sunny and cool. Of course, Seattle does not get a lot of 100 degrees Fahrenheit (37.7 degrees Celsius) days in the summer. Actually, the temperature is not what is so bad, but rather it is the humidity that is oppressive. A day that is 100 degrees Fahrenheit with 85% humidity makes a good day to spend in the pool, or to spend writing Windows PowerShell scripts whilst hugging an air conditioner. Back when I was traveling, the Scripting Wife and I usually ended up in Australia during our summer (and their winter)—it is our favorite way to escape the heat and the humidity. Thus, fall and winter in Charlotte is one of the reasons people move here—to escape the more rugged winters in the north. Anyway…

Yesterday, I wrote a useful function that makes a remote connection to a server running Exchange Server 2010 and brings all of the Exchange commands into the current session. This function uses a technique called implicit remoting.

It is unfortunate that the Get-ExCommand command is not available outside the native Exchange Server Management Shell, because the Exchange commands are not all that discoverable by using normal Windows PowerShell techniques. For example, I would expect to be able to find the commands via the Get-Command cmdlet, but as is shown here, nothing returns.

PS C:\> Get-Command -Module *exchange*

PS C:\>

The Get-ExCommand cmdlet is actually a function and not a Windows PowerShell cmdlet. In reality, it does not make much of a difference that Get-ExCommand is not a cmdlet, except that with a function, I can easily use the Get-Content cmdlet to figure out what the command actually accomplishes. The function resides on the function drive in Windows PowerShell, and therefore the command to retrieve the content of the Get-ExCommand function looks like this:

Get-Content Function:\Get-ExCommand

The command and output associated with that command when run from within the Exchange Server Management Shell are shown in the image that follows.

Image of command output

The following steps are needed to duplicate the Get-ExCommand function:

  1. Open the Windows PowerShell ISE (or some other script editor).
  2. Establish a remote session onto an Exchange Server. Use the New-ExchangeSession function from yesterday’s Hey, Scripting Guy! blog.
  3. Make an RDP connection to a remote Exchange Server and use the Get-Content cmdlet to determine the syntax for the new Get-ExCommand command.
  4. Use the Windows PowerShell ISE (or other script editor) to write a new function that contains the commands from Step 2 inside a new function named Get-ExCommand.

In the image that follows, I run the New-ExchangeSession function and make an implicit remoting session to the server named “ex1,” which is running Exchange Server 2010. This step brings the Exchange commands into the current Windows PowerShell environment and provides commands with which to work when I am creating the new Get-ExCommand function.

Image of command output

Here is a version of the Get-ExCommand function that retrieves all of the Microsoft Exchange commands.

Function Get-ExCommand


 Get-Command -Module $global:importresults |

 Where-Object { $_.commandtype -eq ‘function’ -AND $ -match ‘-‘}

} #end function Get-ExCommand

I copied the portion of the function that retrieves the module name from the $global namespace. It came from the contents of the Get-ExCommand function from the server running Exchange Server 2010. One of the nice things about functions is that they allow the code to be read.

I added the Where-Object to filter out only the functions. In addition, I added the match clause to look for a “-“ in the function name. This portion arose because of the functions that set the working location to the various drive letters.

To search for Exchange cmdlets that work with the database requires the following syntax.

Get-ExCommand | where { $ –match ‘database’}

That is not too bad, but if I need to type it on a regular basis, it rapidly becomes annoying.

In the original Get-ExCommand function, the function uses the $args automatic variable to determine the presence of an argument to the function. When an argument exists, the function uses that and attempts to use the Get-Command cmdlet to retrieve a CmdletInfo object for the command in question. This is helpful because it allows the use of wildcards to discover applicable Windows PowerShell cmdlets for specific tasks.

I decided to add a similar capability to my version of the Get-ExCommand function, but instead of using the $args variable, I created a command-line parameter named Name. To me, it makes the script easier to read. The following is the content of the Get-ExCommand function.

Function Get-ExCommand


 Param ([string]$name)


  {Get-Command -Module $global:importresults |

   Where-Object { $_.commandtype -eq ‘function’ -AND $ -match ‘-‘} }


  {Get-Command -Module $global:importresults |

   Where-Object { $_.commandtype -eq ‘function’ -AND

   $ -match ‘-‘ -AND $ -match $name} }

} #end function Get-ExCommand

The first thing the Get-ExCommand function does is to create the $name parameter. Next, the if statement checks to see if the $name parameter exists on the command line. If it does not exist, the same syntax the previous version utilized appears. If the $name parameter does exist, an additional clause to match the value of the $name parameter appears.

The following code illustrates searching for all Exchange commands related to the database.

Get-ExCommand database

The image that follows illustrates using the Get-ExCommand function, and the associated output.

Image of command output

The complete Get-ExCommand function, including comment-based Help, appears in the Scripting Guys Script Repository.

JM, that is all there is to gaining access to the Get-ExCommand command in a remote Windows PowerShell session. Join me tomorrow for more cool stuff. Until then, keep on scripting.

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

Ed Wilson, Microsoft Scripting Guy

Comments (2)

  1. Ben says:

    This is helpless, the $global:importResults is set in the Exchange's CommonConnectFunctions.ps1 script, which is obviously not needed to make a manual remoting to the Exchange's Remote PowerShell. Hence, during a manual remoting this variable will not be defined, and will not be mapped to the Exchange's imported module, and would be $null (or something else wrong which would break your pseudo-function).

  2. Doug says:

    Ben is correct. The function as written seems to work since if you've got a manual Exchange session most of the commands that are functions are Exchange commands.

    If you run get-excommand | ? {$_.Name -match "clear"} with a manual Exchange session, you'll see Clear-Host as a result which is not an Exchange command. If you run it from a proper Exchange Management Shell, that won't be there.

    Additionally, the actual Get-ExCommand returns too many results as well. If for instance, you import the Active Directory module from an Exchange Management Shell, Get-ExCommand will return those commands as too. Try get-excommand | ? {$_ -match "get-adc"} for instance.

Skip to main content