Powershell Remoting: using imported module cmdlets in a remote pssession Powershell Remoting: using imported module cmdlets in a remote pssession powershell powershell

Powershell Remoting: using imported module cmdlets in a remote pssession


I ended up hacking this to work. What I did was create a local session, import modules into that session and used import-pssession to import modules from the created local session into the remote session. This is slow. If anyone has a better way of doing this, or if someone knows how to get an instance of the base session I'd love to hear from you!

Remoting.psm1

function Export-ModuleToSession { Param(  [ValidateNotNull()]  $session,  [ValidateNotNull()]  $modules ) $computername = $env:computername $modulesToImport = get-module -name $modules invoke-command -session $session -argumentlist @($computername, $modulesToImport) -scriptblock {  Param(   $computername,   $modules  )  write-host ("Creating Temp Session On: " + $computername)  $localSession = New-psSession -computername $computername  $modules | foreach-object {   if($_.ModuleType -ne "Binary") {    $path = $_.path   }   else {    $path = join-path (split-path $_.Path) ("{0}.psd1" -f $_.name)   }   invoke-command -session $localSession -argumentList $path -scriptblock {    Param(     $path    )    $initializeDefaultBTSDrive = $false    set-executionpolicy unrestricted    write-host ("Importing Module To Temp Session: " + $path)    import-module $path   }  }  $initializeDefaultBTSDrive = $false  $modules | foreach-object {    write-host ("Exporting Module: " + $_.name)   import-psSession -session $localSession -Module $_.name  | out-null   } }}

MyModule.psm1

function MyCmdlet {}

RemotingTest.ps1

import-module .\remoting.psm1import-module .\MyModule.psm1try{ $remoteSession = New-PsSession -computerName "RemoteComputer" Export-ModuleToSession -session $remoteSession -modules "MyModule" Invoke-Command -session $remoteSession -scriptblock { MyCmdlet } -verbose -ea Stop}finally{ Remove-PsSession $remoteSession -ea Continue Remove-Module "Remoting" -ea Continue Remove-Module "MyModule" -ea Continue}


As an alternate to what Jonathan mentions, if you have source modules you want to push over the wire, then you can do that without too much trouble. If you have binaries, you might be able to do something similar.but I'd say all bets are off there. Essentially you push the files over as params in a hash, write to temp, then import.

function Export-SourceModulesToSession{    Param(     [Management.Automation.Runspaces.PSSession]     [ValidateNotNull()]     $Session,    [IO.FileInfo[]]    [ValidateNotNull()]    [ValidateScript(    {      (Test-Path $_) -and (!$_.PSIsContainer) -and ($_.Extension -eq '.psm1')    })]   $ModulePaths  )   $remoteModuleImportScript = {     Param($Modules)     Write-Host "Writing $($Modules.Count) modules to temporary disk location"     $Modules |       % {         $path = ([IO.Path]::GetTempFileName()  + '.psm1')         $_.Contents | Out-File -FilePath $path -Force         "Importing module [$($_.Name)] from [$path]"         Import-Module $path       }   }  $modules = $ModulePaths | % { @{Name = $_.Name; Contents = Get-Content $_ } }  $params = @{    Session = $Session;    ScriptBlock = $remoteModuleImportScript;    Argumentlist = @(,$modules);  }  Invoke-Command @params}

Call like

$session = New-PSSession -ComputerName FooExport-SourceModulesToSession $session -ModulePaths '.\module.psm1','.\module2.psm1'

Also theoretically possible, exporting a current localhost session to module and pushing that over the wire -- untested pseudo-code. This might not work...

$localSession = New-PSSession #defaults to localhost# if you don't have modules automatically loading in the profile, etc, then manually load themInvoke-Command -Computer $localSession -ScriptBlock { Import-Module 'foo'; Import-Module '.\module.ps1' }Export-PSSession $localSession -OutputModule TempLocalModule#now that you have TempLocalModule written out, it's possible you can send that thing across the wire in the same way


in case this helps:

if you can switch to PowerShell 3.0, thenthe Get-Module and Import-Module cmdlets support modules on remote computers:

http://technet.microsoft.com/en-us/library/hh857339.aspx#BKMK_REM

It should be possible to run PowerShell on remote computer, that performs Import-Module,without having any ps1 scripts on the remote computer.