Bringing remote commands to your local session

How can you manage multiple technologies installed on separate machines that expose their management surface through cmdlets?  One approach would be to open remote desktop connection to each of those machines, another approach would be to send commands using Invoke-Command and PowerShell Remoting.  But remote desktop is not a feasible solution for automation and invoking remote commands using Invoke-Command cmdlet can sometimes get burdensome – tab completion is missing, verbose incantations are needed for passing arguments to remote commands and Get-Help -Online doesn’t quite work in a remote session.

That’s where IMPLICIT REMOTING comes to play – ability to import remote commands into your local session. One can even store the information about imported commands on disk for later use, details in a later post. Implicit remoting is a feature that smoothes out the user experience of invoking remote commands.

Importing remote commands into local session

Let’s see how one can import a remote command into a local session. First – let’s ask Import-PSSession cmdlet to look in the remote session $s, take all the remote commands matching "*-Process" wildcard, add a "Remote" prefix to their noun, and then present them to me as if they were local commands:

PS> $s = New-PSSession -ComputerName lukasza5 -Credential REDMOND\lukasza
PS> Import-PSSession -Session $s -CommandName *-Process -Prefix Remote

ModuleType Name                      ExportedCommands
---------- ----                      ----------------
Script     tmp_a50e3c88-46f1-4c25... {Stop-Process, Get-Process, Debug-Process, Wait-Process...}

Implicit remoting experience

The basic promise behind implicit remoting is that you can work with remote commands using local syntax. In particular – after Import-PSSession did its magic I can invoke remote commands as if they were local commands. Let’s see if Get-RemoteProcess really works on a different machine than Get-Process:

PS> Get-RemoteProcess -Name w*host

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    313      10    39000      51044   162     2.18   2348 wsmprovhost

PS> Get-Process -Name w*host

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    216      11     2056       6132    61     0.09   1208 WUDFHost

Below is a list of other things that you can try:

  • Get-RemotePr<tab>: tab completion on remote command and parameter names
  • Get-Help Get-RemoteProcess: downloading help content from remote session and displaying it on a local box
  • Get-RemoteProcess -Name $localVariable: binding local variables as arguments to parameters of remote commands
  • Get-RemoteProcess -AsJob: invoking remote commands as background jobs using an extra switch parameter added to remote commands
  • Get-RemoteProcess -OutVariable global:localVariable | Out-Null: storing results of remote invocation in a local variable (scope prefix is unfortunately necessary because of implementation details)
  • Get-RemoteProcess | Select-Object -Last 5: mixing remote and local commands in a single pipeline


Lukasz Anforowicz [MSFT]

Windows PowerShell Developer

Microsoft Corporation