Saving remote session to your local disk

Saving remote session to your local disk

  • Comments 7

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.

Thanks,

Lukasz Anforowicz [MSFT]
Windows PowerShell Developer
Microsoft Corporation

Leave a Comment
  • Please add 3 and 5 and type the answer here:
  • Post
  • Wow this is really amazing.  I love PowerShell.  I just wrote a <a href="http://blog-powershell.blogspot.com/2009/12/remove-user-in-domaina-from-group-in.html"><u>script</u></a> that overcomes a problem with searching multiple domains using the new ActiveDirectory Module and I did have to do an Invoke-Command.  This is so much more elegant.  

    Thanks

    Cameron

  • I am remoting to a Microsoft HPC box. How do I Import the HPC Cmdlets to my local session?

  • Doug,

    Import/Export-PSSession cmdlets internally invoke Get-Command in the remote session to get metadata of the remote commands.  CommandName, CommandType and Module parameters of Import/Export-PSSession cmdlets are directly passed to the remotely invoked Get-Command.  You can try manually invoking remote Get-Command (i.e. via Invoke-Command) to see what parameters will give you exactly the set of commands you want to see in your implicit remoting experience.

    I am not very familiar with HPC cmdlets, but according to their documentation (http://resourcekit.windowshpc.net/AT%20A%20GLANCE/Papers1/Windows_HPC_Server_2008_Management_Overview.pdf) all their cmdlets use nouns beginning with "Hpc" ).  Therefore something like this should work for you:

    Import-PSSession $s -CommandName *-Hpc* -CommandType cmdlet

  • @Doug,

    Remember, you'll need to be remoting to a Server 2008 R2-based HPC box to import the cmdlets locally.  That's because it takes v2 to do this.  I'm not sure if you can go an install v2 on a Server 2008 infrastructure and remain supported...

  • Hello,

    I need to write code in C# that execute Exchange cmdlet as well as basic cmdlet.

    For example:

    Input to my code can be:

    Get-Exchangeserver | Format-list

    According to code , if I use:

    WSManConnectionInfo connectionInfo = new WSManConnectionInfo();  

    Then : cmdlets like, Get-process, Format-list, Out-String,..... is recognized whereas Exchange cmdlet is not known as Get-mailbox, Get-Exchangeserver,...

    If I use the following constructore:

    WSManConnectionInfo RemoteConnectionInfo = new WSManConnectionInfo(serverUri, schema, credential);

    The opposite happens. I mean Onlty exchange server cmdlets are known.

    Get-exchangeserver | Format-list

    The "Format-list" is not recognized a cmdlet,object,function,...

    What shall I do?

    Regards,

    mgeriesa

  • "I'm not sure if you can go an install v2 on a Server 2008 infrastructure and remain supported..."

    -I'm pretty sure you can't

  • Hello,

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

    We can easily bypass the password prompt by pressing escape button two times and I'm able to import PSSession (From Module) and executed remote command successfully without any password.

    This leads to serious security issue, isn't it?

Page 1 of 1 (7 items)