2013-08-16 12 views
6

Sto tentando di eseguire un cmdlet invoke-command utilizzando C# ma non riesco a capire la sintassi corretta. Voglio solo eseguire questo semplice comando:Richiama il comando powershell remoto da C#

invoke-command -ComputerName mycomp.mylab.com -ScriptBlock {"get-childitem C:\windows"} 

Nel codice C#, ho fatto quanto segue:

InitialSessionState initial = InitialSessionState.CreateDefault(); 
Runspace runspace = RunspaceFactory.CreateRunspace(initial); 
runspace.Open(); 
PowerShell ps = PowerShell.Create(); 
ps.Runspace = runspace; 
ps.AddCommand("invoke-command"); 
ps.AddParameter("ComputerName", "mycomp.mylab.com"); 
ps.AddParameter("ScriptBlock", "get-childitem C:\\windows"); 
foreach (PSObject obj in ps.Invoke()) 
{ 
    // Do Something 
} 

Quando eseguo questo, ottengo un'eccezione:

Cannot bind parameter 'ScriptBlock'. Cannot convert the "get-childitem C:\windows" value of type "System.String" to type "System.Management.Automation.ScriptBlock". 

Sto indovinando che ho bisogno di usare il tipo ScriptBlock qui da qualche parte, ma non so come. Questo è solo un semplice esempio per iniziare, il caso di utilizzo reale implicherebbe l'esecuzione di un blocco di script più grande con più comandi al suo interno, quindi qualsiasi aiuto su come farlo sarebbe molto apprezzato.

Grazie

risposta

9

Ah, il parametro di ScriptBlock stesso deve essere di tipo ScriptBlock.

codice completo:

InitialSessionState initial = InitialSessionState.CreateDefault(); 
Runspace runspace = RunspaceFactory.CreateRunspace(initial); 
runspace.Open(); 
PowerShell ps = PowerShell.Create(); 
ps.Runspace = runspace; 
ps.AddCommand("invoke-command"); 
ps.AddParameter("ComputerName", "mycomp.mylab.com"); 
ScriptBlock filter = ScriptBlock.Create("Get-childitem C:\\windows"); 
ps.AddParameter("ScriptBlock", filter); 
foreach (PSObject obj in ps.Invoke()) 
{ 
    // Do Something 
} 

Mettere la risposta qui se qualcuno trova utile in futuro stringa di

3

Uno scriptblock deve corrispondere al formato "{...}" Utilizza il codice follow. sarà ok:

ps.AddParameter("ScriptBlock", "{ get-childitem C:\\windows }"); 
+0

ah bello, mi salva da fare un oggetto filtro esplicito, grazie – NullPointer

0

si utilizza formato breve:

ps.AddParameter("ScriptBlock", ScriptBlock.Create("Get-childitem C:\\Windows")); 
0

Un approccio alternativo nel caso in cui sia forse più appropriato in alcuni casi.

 var remoteComputer = new Uri(String.Format("{0}://{1}:5985/wsman", "HTTP", "ComputerName")); 
     var connection = new WSManConnectionInfo(remoteComputer, null, TopTest.GetCredential()); 

     var runspace = RunspaceFactory.CreateRunspace(connection); 
     runspace.Open(); 

     var powershell = PowerShell.Create(); 
     powershell.Runspace = runspace; 

     powershell.AddScript("$env:ComputerName"); 

     var result = powershell.Invoke(); 

https://blogs.msdn.microsoft.com/schlepticons/2012/03/23/powershell-automation-and-remoting-a-c-love-story/