2012-03-22 126 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不會在它創建的同一會話中識別出增加的驅動器。

相關問題