2012-03-22 168 views
1

我需要能够通过C#运行空间执行驻留在远程计算机上的PS1脚本。在C#运行空间中的另一台远程服务器上运行远程PowerShell脚本

要清楚我的意思是:我创建的服务驻留在服务器A上。它使用以下方法为服务器B创建远程运行空间。通过运行空间,我试图调用驻留在服务器C上的脚本来对抗服务器B.如果它有帮助,当前服务器是IS服务器C,但不能保证永远都是这样。

这里是我用来进行远程调用的方法:设置为PowerShell脚本我想要运行

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”。例如:

"& \"\\\\remoteserveraddress\\PathToScript\\Install.ps1\" -Parameter;Import-Module Modulename;CustomCommand-FromModule -parameter(s) -ErrorAction stop" 

如果我说我要上运行该脚本在远程计算机上,在PowerShell控制台,我可以只给下面的命令:

& "\\remoteserverC\PathToScript\Install.ps1" -Parameter 

然而,这只是拒绝为我工作,如果我尝试通过C#运行空间运行它。

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

"& \"\\\\remoteserverC\\PathToScript\\Install.ps1\" -Parameter" 

我得到以下错误:

The term '\remoteserverC\PathToScript\Install.ps1' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

我试过有和没有“&”,并与没有参数。我已经可以调用直接位于远程计算机“c:\ ... \ Install.ps1”而不是“\\ remoteserver \ ... \ Install.ps1”上的脚本,但这样做会非常有益直接调用远程脚本。

我已经搜索了很多很多网页在谷歌和这里在stackoverflow,但我一直没能找到任何有助于克服这个问题。任何帮助,将不胜感激!谢谢!

+0

Install.ps1的内容是什么? – Kiquenet 2012-05-24 09:56:53

+1

@Kiquenet它基本上配置一个环境并加载一个模块供其他脚本使用。 它执行与我的解决方案相同的驱动器映射检查,将文件从临时环境中复制到服务器,然后卸载(如果存在)并重新安装模块。然后它导入模块。 – Arangarx 2012-05-24 18:07:13

回答

2

我从来没有这样做直接工作,似乎是一个安全“功能”,你不能访问远程工作时使用UNC地址的第三台机器。然而,我却能够找到一个解决方案,对我来说非常合适。

而不是直接调用\\服务器\共享地址,我动态映射网络驱动器在机器上我试图运行该脚本对具有该脚本的计算机上的共享。 (从A远程运行,将B上的驱动器映射到C上的共享)。然后,我通过那个驱动器调用我的脚本,它就像一个魅力。此字符串是我传递到RunRemoteScript上述方法:

"$net = new-object -ComObject WScript.Network;" + 
"if(!($net.EnumNetworkDrives() -contains \"S:\"))" + 
    "{Write-Host \"S: Drive Not Currently Mapped. Mapping to \\\\" + RemoteServerC + "\\Share.\";" + 
    "$net.MapNetWorkDrive(\"S:\",\"\\\\" + RemoteServerC + "\\Share\",$false,\"username\",\"password\")};" + 
"Get-PSDrive | Write-Verbose;" + 
"& \"S:\\PathToScript\\Install.ps1\" -noPrompt;" 

RemoteServerC是可变我通过在在用户配置文件中定义。

下面是相同的代码只是PowerShell脚本如果有人需要它(用PowerShell的变量替换RemoteServerC你需要之前要设置或硬编码:

$net = new-object -ComObject WScript.Network 
if(!($net.EnumNetworkDrives() -contains "S:")) 
{ Write-Host "S: Drive Not Currently Mapped. Mapping to \\remoteserverC\Share." 
    $net.MapNetWorkDrive("S:","\\remoteserverC\Share",$false,"username","password") 
} 
Get-PSDrive | Write-Verbose 
& "S:\\PathToScript\\Install.ps1\" -noPrompt;" 

首先,我设置对象是能够映射驱动器,然后检查映射到远程机器上是否已有“s”驱动器。如果没有,则使用我们在Active Directory中设置的名称和密码将共享映射到远程计算机上的“s”驱动器以运行此服务。

我包含Get-PSDrive命令,因为它似乎强制powershell重新加载可用驱动器的列表。这似乎只是第一次尝试在PowerShell会话中执行此操作(并且通过c sharp我不知道它是否真的有必要,我将它包括在内以保证安全)。显然,如果您使用MapNetworkDrive,powershell不会在它创建的同一会话中识别出增加的驱动器。

相关问题