Saving remote session to your local disk

Read the previous post on implict remoting to learn how the Import-PSSession cmdlet makes it easier to work with remote commands by presenting them as if they were local commands. This user experience saves you the trouble of typing long Invoke-Command incantations to pass arguments to remote commands or to download remote help content.

The next great thing would be to jump straight into the implicit remoting experience without having to explicitly set up a remote session each time and having to remember how to invoke Import-PSSession… This is where Export-PSSession cmdlet comes handy – it can be used to save the remote session and the remote commands to a local disk.

Temporary implicit remoting modules

Let’s recall how one can import remote commands into a local session:

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...}

Import-PSSession cmdlet creates a temporary module containing local functions that act as proxies for remote commands. The module is then implicitly imported into the local session by the Import-PSSession cmdlet. The module and all the temporary files are deleted whenever the user explicitly removes the module or when the remote session is closed:

PS> Remove-PSSession $s

Saving an implicit remoting module

Instead of working with temporary modules created by Import-PSSession, one can save a module in the file system. This is done one with the Export-PSSession cmdlet. Example below asks Export-PSSession cmdlet to look in the remote session $s, take all the remote commands matching "*-Process" wildcard, and save them to "MyRemoteCommands" module. The example explicitly says that it would be okay to clobber local commands that have the same name as the imported, remote commands.

PS> $s = New-PSSession -ComputerName lukasza5 -Credential REDMOND\lukasza
PS> Export-PSSession -Session $s -CommandName *-Process -OutputModule MyRemoteCommands -AllowClobber

    Directory: C:\Users\lukasza\Documents\WindowsPowerShell\Modules\MyRemoteCommands

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        2009-12-29  11:50 AM      20535 MyRemoteCommands.psm1
-a---        2009-12-29  11:50 AM         99 MyRemoteCommands.format.ps1xml
-a---        2009-12-29  11:50 AM        598 MyRemoteCommands.psd1

PS C:\> Remove-PSSession $s

You can see that Export-PSSession cmdlet saved a new module under the default user path from ${env:PSModulePath}. No remote commands have been imported into the local session yet – there is no Get-RemoteProcess command and Get-Process works against the local machine.

Importing a saved implicit remoting module

After implicit remoting module is saved, one can invoke the remote commands without having to ever again use New-PSSession, Invoke-Command, Import-PSSession or Export-PSSession. Let’s see how that works:

PS> Import-Module MyRemoteCommands -Prefix Remote

In the example above, I imported the remote commands from the saved module into the local session (I used the -Prefix parameter to avoid clobbering my local commands). No connection has been made to the remote computer yet, but I can see all the remote commands in Get-Command and use tab completion when typing them at the command prompt.

Let’s try to invoke one of the commands:

PS> Get-RemoteProcess -Name w*host
Creating a new session for implicit remoting of "Get-Process" command...

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    237       9    24372      35556   146     0.95   4344 wsmprovhost

The remote invocation worked. I didn’t even have to create a remote session – implicit remoting took care of that when I first attempted to use a remote command from the saved module. I’ve been prompted for the password, but all the other connection parameters (i.e. computer name, http proxy settings) were stored in the saved module.


Lukasz Anforowicz [MSFT]

Windows PowerShell Developer

Microsoft Corporation