Powershell Remoting: использование импортированных командлетов модулей в удаленном pssession - PullRequest
14 голосов
/ 14 мая 2010

Есть ли способ использовать модули, которые были импортированы в локальный сеанс в удаленном сеансе? Я посмотрел на import-pssession, но не знаю, как получить локальную сессию. Вот пример того, что я хочу сделать.

import-module .\MyModule\MyModule.ps1
$session = new-pssession -computerName RemoteComputer
invoke-command -session $session -scriptblock { Use-CmdletFromMyModule }

Кроме того, я не хочу импортировать модуль в удаленном сеансе, поскольку файлы ps1 отсутствуют на этом сервере.

Ответы [ 7 ]

10 голосов
/ 14 мая 2010

В итоге я взломал это, чтобы работать. Я создал локальный сеанс, импортировал модули в этот сеанс и использовал import-pssession для импорта модулей из созданного локального сеанса в удаленный сеанс. Это медленно. Если у кого-то есть лучший способ сделать это, или если кто-то знает, как получить экземпляр базовой сессии, я хотел бы услышать от вас!

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
}
3 голосов
/ 26 апреля 2012

В качестве альтернативы тому, что упоминает Джонатан, если у вас есть исходные модули, которые вы хотите протолкнуть через провод, то вы можете сделать это без особых проблем. Если у вас есть бинарные файлы, вы можете сделать что-то подобное. Но я бы сказал, что все ставки там. По сути, вы передаете файлы как параметры в хэш, записываете в temp, затем импортируете.

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
}

Звоните как

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

Теоретически возможно также экспортировать текущий сеанс localhost в модуль и отправить его по проводам - ​​непроверенный псевдокод. Это может не сработать ...

$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
2 голосов
/ 22 ноября 2012

, если это помогает:

, если вы можете переключиться на PowerShell 3.0 , тогда Командлеты Get-Module и Import-Module поддерживают модули на удаленных компьютерах:

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

Должна быть возможность запуска PowerShell на удаленном компьютере, который выполняет Import-Module, без каких-либо сценариев PS1 на удаленном компьютере.

0 голосов
/ 04 августа 2017

Так что я искал нечто подобное ... В моем случае мне просто нужно было экспортировать одну функцию в удаленный сеанс ... Это то, что я придумал. Может быть, вы могли бы повторить это, чтобы попробовать это. Он не работает с внутренними командами, но он работает с функциями в пользовательских модулях (в тестировании, которое я сделал).

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 голосов
/ 06 сентября 2016

использовать аутентификацию credssp

invoke-command -computername $localSession -Credential $Credential -Authentication Credssp
0 голосов
/ 11 августа 2011

Я бы предложил что-то вроде:

$rs = New-PSSession -ComputerName "RemoteComputer"
Invoke-Command -Session $rs -scriptblock {import-module ActiveDirectory}
Import-PSSession -Session $rs -Module ActiveDirectory

С тех пор вы можете использовать командлеты ActiveDirectory в своем сеансе.

Надеюсь, это поможет.

0 голосов
/ 14 мая 2010

Я не верю, что ты можешь. Вы можете пойти другим путем - импортировать команды, загруженные на удаленном компьютере, в удаленный сеанс, запущенный на локальном компьютере. Вы можете указать скрипт для invoke-command, и он скопирует этот скрипт на удаленный компьютер и запустит его. Но если вам нужны оснастки или дополнительные модули, вам необходимо убедиться, что они установлены на каждом удаленном компьютере, а затем загрузить их в удаленный сеанс с помощью команд или вашего скрипта.

...