Powershell Remoting: using imported module cmdlets in a remote pssession

前端 未结 7 2103
我在风中等你
我在风中等你 2021-02-05 12:34

Is there a way to use modules that were imported in a local session in a remote session? I looked at import-pssession, but I don\'t know how to get the local session. Here\'s a

相关标签:
7条回答
  • 2021-02-05 12:49

    I don't believe you can. You can go the other way - import commands loaded on the remote machine into your remote session running on the local machine. You can specify a script to invoke-command and it will copy that script over to the remote machine and run it. But if you require snapins or additional modules, you will need to make sure those are installed on each remote machine and then load them into the remote session via commands or your script.

    0 讨论(0)
  • 2021-02-05 12:50

    in case this helps:

    if you can switch to PowerShell 3.0, then the 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.

    0 讨论(0)
  • 2021-02-05 12:56

    So I was looking for something similar... In my case I just needed to export a single function to a remote session... this is what I came up with. Maybe you could loop over it to try it. It doesn't work with internal commands, but it does work on functions in custom modules (in the testing I've done).

    function Export-FunctionToSession
    {
        [CmdletBinding()]
        [Alias()]
        [OutputType([int])]
        Param
        (
            [Parameter(Mandatory=$true,
                       ValueFromPipelineByPropertyName=$true,
                       Position=0)]
            $Session,
            [Parameter(Mandatory=$true,
                       ValueFromPipelineByPropertyName=$true,
                       Position=0)]
            $FunctionName
        )
        $script = "Function $functionName(){" + (Get-Command $functionName).definition + '}'
        $scriptBlock = {Invoke-Expression $using:script}
        Invoke-Command -Session $session -ScriptBlock $scriptBlock
    }
    
    0 讨论(0)
  • 2021-02-05 13:00

    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.psm1
    import-module .\MyModule.psm1
    
    try
    {
     $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
    }
    
    0 讨论(0)
  • 2021-02-05 13:06

    use credssp authentication

    invoke-command -computername $localSession -Credential $Credential -Authentication Credssp
    
    0 讨论(0)
  • 2021-02-05 13:07

    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 Foo
    Export-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 them
    Invoke-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
    
    0 讨论(0)
提交回复
热议问题