2010-05-13 26 views
14

Gibt es eine Möglichkeit, Module zu verwenden, die in einer lokalen Sitzung in einer Remotesitzung importiert wurden? Ich habe mir import-pssession angesehen, aber ich weiß nicht, wie ich die lokale Sitzung bekommen soll. Hier ist ein Beispiel, was ich machen möchte.Powershell Remoting: Verwenden importierter Modul-Cmdlets in einer Remote-PSSession

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

Auch ich mag nicht in der Remote-Sitzung importieren-Modul, da die ps1-Dateien sind nicht auf diesem Server.

Antwort

0

Ich glaube nicht, dass Sie können. Sie können den anderen Weg gehen - Befehle, die auf dem Remote-Computer geladen sind, in Ihre Remote-Sitzung importieren, die auf dem lokalen Computer ausgeführt wird. Sie können ein Skript für invoke-command angeben und es wird dieses Skript auf den Remote-Computer kopieren und ausführen. Wenn Sie jedoch Snapins oder zusätzliche Module benötigen, müssen Sie sicherstellen, dass diese auf jedem Remotecomputer installiert sind, und sie dann über Befehle oder Ihr Skript in die Remotesitzung laden.

10

Ich endete damit, das zu hacken. Ich habe eine lokale Sitzung erstellt, Module in diese Sitzung importiert und import-psession Module aus der erstellten lokalen Sitzung in die Remote-Sitzung importiert. Das ist langsam. Wenn jemand eine bessere Möglichkeit hat, dies zu tun, oder wenn jemand weiß, wie man eine Instanz der Basissitzung bekommt, würde ich gerne von Ihnen hören!

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

Ich stehe korrigiert. :-) Netter Ansatz, um die Fähigkeit zu nutzen, Commands vom Remote-Computer zu importieren und auf den Kopf zu stellen, um sie vom lokalen Computer zu importieren. BTW importieren Sie basierend auf Pfad (anstelle von Modulname), weil Sie auf ein Problem stoßen? –

+0

Sie können ein Modul nur dann anhand des Namens importieren, wenn sich die Moduldatei an einem der Standardmodulpositionen befindet. Wenn nicht, müssen Sie ihm den Dateipfad geben. Ich stieß auf ein Problem mit Assembly-Modulen, die aus einem Modul-Manifest psd1 importiert werden. Die PSModuleInfo.Path-Eigenschaft für ein Binärmodul verweist auf die DLL anstelle von PSD1. Wenn Sie direkt von der DLL importieren, schlägt import-psession fehl. Daher alle Voodoo, um die PSD1-Datei für ein Assembly-Modul zu erhalten. –

+0

Verwenden Sie diese Methode noch oder haben Sie einen besseren Weg gefunden? – icnivad

0

würde ich so etwas vorschlagen:

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

Seitdem können Sie ActiveDirectory-Cmdlets in Ihrer Sitzung verwenden.

Hoffe, das hilft.

3

Als Alternative zu dem, was Jonathan erwähnt, wenn Sie Quellmodule haben, die Sie über die Leitung schieben möchten, können Sie das ohne große Probleme tun. Wenn Sie Binärdateien haben, können Sie in der Lage sein, etwas Ähnliches zu tun. Aber ich würde sagen, dass alle Wetten weg sind. Im Wesentlichen schieben Sie die Dateien als Parameter in einem Hash, schreiben Sie in Temp, und importieren Sie dann.

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 
} 

Anruf wie

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

auch theoretisch möglich, eine aktuelle lokale Host-Sitzung zu exportieren, dass über den Draht Modul und Schieben - ungetestet Pseudocode. Dies könnte nicht funktionieren ...

$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

Tipp: Wenn das Modul im PSModule Pfad befindet oder bereits geladen ist, kann es sinnvoll sein, ModulePaths Bewertung zu ändern (Get-Modul $ Modul) .Path – 2xMax

+0

Super, funktioniert sehr gut! – ssougnez

2

falls dies hilft:

wenn Sie Powershell 3 umschalten. 0, dann die Get-Module und Import-Module Cmdlets Support-Module auf Remote-Computern:

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

Es sollte möglich sein Powershell auf dem Remote-Computer ausführen kann, die Import-Module führt, ohne mit ps1-Skripte auf dem Remote-Computer.

+0

Wahrscheinlich brauchen wir PS 3.0 an beiden Enden, nicht wahr? – icnivad

-2

Verwendung CredSSP-Authentifizierung

invoke-command -computername $localSession -Credential $Credential -Authentication Credssp 
0

Also ich suchte etwas Ähnliches ... In meinem Fall musste ich nur eine einzige Funktion zu einer Remote-Sitzung exportieren ... das ist, was ich kam mit. Vielleicht könntest du darüber hinweglaufen, um es zu versuchen. Es funktioniert nicht mit internen Befehlen, aber es funktioniert mit Funktionen in benutzerdefinierten Modulen (in den Tests, die ich gemacht habe).

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 
}