2013-11-25 29 views
7

我試着用下面的代碼運行在C#腳本localwindows.ps1 PowerShell腳本文件(example.ps1):要調用從C#

   PSCredential credential = new PSCredential(userName, securePassword); 
       WSManConnectionInfo connectionInfo = new WSManConnectionInfo(false, "machineName", 5985, "/wsman", shellUri, credential); 
       using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo)) 
       { 

        runspace.Open(); 
        String file = "C:\\localwindows.ps1"; 
        Pipeline pipeline = runspace.CreatePipeline(); 
        pipeline.Commands.AddScript(file); 
        pipeline.Commands.Add("Out-String"); 
        Collection<PSObject> results = pipeline.Invoke(); 
       } 

但是,得到的異常: '術語' C:\ localwindows .ps1'不被識別爲cmdlet,函數,腳本文件或可操作程序的名稱。

所以我試過如下:

PSCredential credential = new PSCredential(userName, securePassword); 
WSManConnectionInfo connectionInfo = new WSManConnectionInfo(false, "machineName", 5985, "/wsman", shellUri, credential); 
using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo)) 
{ 

    runspace.Open(); 

    using (PowerShell powershell = PowerShell.Create()) 
    { 
     powershell.Runspace = runspace;   

     PSCommand new1 = new PSCommand(); 
     String machinename = "machinename"; 
     String file = "C:\\localwindows.ps1"; 
     new1.AddCommand("Invoke-Command"); 
     new1.AddParameter("computername", machinename); 
     new1.AddParameter("filepath", file);   


     powershell.Commands = new1; 
     Console.WriteLine(powershell.Commands.ToString()); 
     Collection<PSObject> results = powershell.Invoke(); 

    } 

我得到的錯誤:「找不到路徑‘C:\ localwindows.ps1’。因爲它不存在」

但是使用命令「Invoke-Command -ComputerName」machineName「-filepath C:\ localwindows.ps1」,從本地機器的powershell在遠程機器上創建了一個新帳戶。

如何從C#調用腳本localwindows.ps1? 如何通過C#執行命令「Invoke-Command -ComputerName」machineName「-filepath C:\ localwindows.ps1」?

腳本localwindows.ps1是

$comp = [adsi]「WinNT://machinename,computer」 
$user = $comp.Create(「User」, "account3") 
$user.SetPassword(「change,password.10") 
$user.SetInfo() 

回答

3

其實你的調用方式應該工作。但在這兩個示例中,腳本c:\localwindows.ps1都必須駐留在本地計算機上。在Invoke-Command的情況下,它將從本地計算機複製到遠程計算機。

如果在調用命令的情況下,腳本已經存在於遠程計算機上,你不需要它複製,刪除FilePath參數,並補充一點:

new1.AddParameter("Scriptblock", ScriptBlock.Create(file)); 
+0

我試過管道pipeline.Commands.AddScript(System.IO.File.ReadAllText(file));.我在表達式或語句中出現錯誤:'意外的標記' ​​WinNT://machineName ''。 而相同的腳本使用invoke-command創建本地用戶帳戶。我嘗試瞭解決方案 - 我試過解決方案 - pipeline.Commands.AddScript(System.IO.File.ReadAllText(「。」+ file)); 該程序無法找到該文件。 –

+0

我試過 - new1.AddParameter(「Scriptblock」,「{。」+ file +「}」); 我收到錯誤 - '無法綁定參數'ScriptBlock'。無法將類型「System.String」的「{C:\ localwindows.ps1}」值轉換爲鍵入「System.Management.Automation.ScriptBlock」。 –

+0

查看已更新的答案。我相信問題的癥結在於腳本不在本地計算機的'c:\ localwindows.ps1'上。 –

0

我已經有一篇文章介紹了通過WinRM從.NET運行Powershell的簡單方法,網址爲http://getthinktank.com/2015/06/22/naos-winrm-windows-remote-management-through-net/

如果您想複製它,它的代碼位於單個文件中,它也是一個NuGet包,其中包含對System.Management.Automation的引用。它自動管理可信主機,可以運行腳本塊,併發送文件(這不是真的支持,但我創建了一個工作)。返回始終是Powershell的原始對象。

// this is the entrypoint to interact with the system (interfaced for testing). 
var machineManager = new MachineManager(
    "10.0.0.1", 
    "Administrator", 
    MachineManager.ConvertStringToSecureString("xxx"), 
    true); 

// for your specific issue I think this would be easier 
var results = machineManager.RunScript(
    File.ReadAllText("C:\\LocalWindows.ps1")); 

// will perform a user initiated reboot. 
machineManager.Reboot(); 

// can run random script blocks WITH parameters. 
var fileObjects = machineManager.RunScript(
    "{ param($path) ls $path }", 
    new[] { @"C:\PathToList" }); 

// can transfer files to the remote server (over WinRM's protocol!). 
var localFilePath = @"D:\Temp\BigFileLocal.nupkg"; 
var fileBytes = File.ReadAllBytes(localFilePath); 
var remoteFilePath = @"D:\Temp\BigFileRemote.nupkg"; 
machineManager.SendFile(remoteFilePath, fileBytes); 

如果有幫助請標記爲答覆。我一直在使用我的自動化部署一段時間。如果您發現問題,請留下評論。