2012-03-22 65 views
1

远程服务器上,我需要能够导入通过C#运行空间驻留在远程机器上的模块。导入一个PowerShell模块中的C#运行空间

要清楚我的意思是:我创建的服务驻留在服务器A上。它使用以下方法为服务器B创建远程运行空间。通过运行空间我试图导入一个模块在服务器B.

这里是我用来进行远程调用的方法:

internal Collection<PSObject> RunRemoteScript(string remoteScript, string remoteServer, string scriptName, out bool scriptSuccessful) 
    { 
     bool isLocal = (remoteServer == "localhost" || remoteServer == "127.0.0.1" || remoteServer == Environment.MachineName); 

     WSManConnectionInfo connectionInfo = null; 

     if (!isLocal) 
     { 
      connectionInfo = new WSManConnectionInfo(new Uri("http://" + remoteServer + ":5985")); 
     } 

     PsHostImplementation myHost = new PsHostImplementation(scriptName); 

     using (Runspace remoteRunspace = (isLocal ? RunspaceFactory.CreateRunspace(myHost) : RunspaceFactory.CreateRunspace(myHost, connectionInfo))) 
     { 
      remoteRunspace.Open(); 
      using (PowerShell powershell = PowerShell.Create()) 
      { 
       powershell.Runspace = remoteRunspace; 

       Pipeline pipeline = remoteRunspace.CreatePipeline(); 

       pipeline.Commands.AddScript(remoteScript); 

       Collection<PSObject> results = pipeline.Invoke(); 

       remoteRunspace.Close(); 

       scriptSuccessful = myHost.ScriptSuccessful; 
       return results; 
      } 
     } 
    } 

“remoteScript”设置为PowerShell脚本我想跑步。例如:

"Import-Module Modulename;CustomCommand-FromModule -parameter(s) -ErrorAction stop" 

模块未packedged一起它的一个PSD1,PSM1,并且位于C一堆脚本文件:所述远程服务器(服务器B)上\\ Powershell的\模块名和我已经测试并确保它正在调用C:\\ Powershell \ ModuleName目录中的ModuleName.psd1文件。

里面的ModuleName.psd1文件是行:

ModuleToProcess = 'ModuleName.psm1' 

不过,我得到一个非常奇怪的错误,如果我试图通过C#的运行空间来运行它。

如果我在下面发作为参数传递给 “remoteScript”:

​​

我收到以下错误:

System.Management.Automation.RemoteException: The module to process 'ModuleName.psm1', listed in field 'ModuleToProcess' of module manifest 'C:\Powershell\ModuleName\ModuleName.psd1' was not processed because no valid module was found in any module directory.

该模块中的“$ ENV的一个存在: PSModulePath的位置,并确实显示如果你运行:

get-module -listAvailable 

我也试过把完全合格的p运行到psd1文件中的ModuleName.psm1文件。当我这样做(或者什么是由以下x0n建议)我得到几乎相同的错误:

The module to process 'C:\Powershell\ModuleName\ModuleName.psm1', listed in field 'ModuleToProcess' of module manifest 'C:\Powershell\ModuleName\ModuleName.psd1' was not processed because no valid module was found in any module directory.

在这一点上,我真的不知道哪里去了,或者即使这实际上是可能的。我到处找,发现了一些事情,似乎有关,但它从来不是完全一样,并往往是我已经克服或只是还没有(据我所知)碰到尚未问题。任何帮助,将不胜感激!谢谢!

+1

尝试在PSD1使用ModuleToProcess =联接路径$ psscriptroot 'modulename.psm1'。 – x0n 2012-03-23 14:09:52

+0

感谢x0n,但我仍然遇到错误。我在原文中增加了一些细节。 – Arangarx 2012-03-27 15:43:09

+1

你能通过命令行远程导入模块吗? – 2012-04-19 03:32:34

回答

1

这是一个有点,因为我解决了这个,所以我耽搁道歉。这个解决方案实际上相当简单,虽然有点不可思议。

要解决这个问题,在我ModuleName.psd1注释掉:

ModuleToProcess = 'ModuleName.psm1' 

我把它添加到嵌套模块来代替:

NestedModules = Join-Path $psscriptroot 'ModuleName.psm1' 

坦率地说,我不知道是什么原因让这对模块加载成功,但它为我工作。

一段时间,因为我解决了这个所以它可能有一些微小的一步,我错过了在这里它已经有点。如果这不适合你,让我知道你遇到了什么问题,然后我可以让你知道,如果这是额外的我不得不做的。但我相当确定这只是一切。

1

我怀疑你需要做两件事情:

  1. 使用绝对路径.psd1文件:否则只能模块$env:PSModulePath发现将被视为(这并不重要的脚本做负载运行的位置)。

  2. 确保您可以加载远程脚本。除非已签名,否则缺省或RemoteSigned执行策略将阻止远程脚本。

+0

感谢您的反馈。你提到的两个步骤绝对是任何人需要做的事情(这些事情我已经确定是我的故障排除的一部分),但这些都不是最终的问题。我将发布我的最终解决方案。 – Arangarx 2012-05-24 17:23:42

1

我发现,如果你的模块是建立在一个新的.NET运行时(比如.NET 4.0),你试图将其加载到PowerShell的2.0(基于.NET 3.5),这可能是一个问题。要解决此问题,您需要确保在.net 4中加载PowerShell或调用进程。0 clr。

您可以通过添加enty在* .exe.config(创建powershell.exe.config如果不存在的话)支持的运行时适用的做到这一点。

我测试了这对上述问题的伟大工程。

+0

我已经解决了这个问题(我刚刚还没有发布解决方案,但我的错误),但这听起来像是一件好事,只要尝试再次出现问题就可以尝试。谢谢! – Arangarx 2012-05-24 17:26:10