NullPointer
NullPointer

Reputation: 2184

Invoke remote powershell command from C#

I'm trying to run an invoke-command cmdlet using C# but I can't figure out the right syntax. I just want to run this simple command:

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

In C# code, I have done the following:

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
}

When I run this, I get an exception:

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

I'm guessing I need to use ScriptBlock type here somewhere, but don't know how to. This is just a simple example to get started with, the real use case would involve running a larger script block with multiple commands in it, so any help on how to do this would be highly appreciated.

Thanks

Upvotes: 11

Views: 13479

Answers (4)

Alexis Coles
Alexis Coles

Reputation: 1317

An alternative approach in case it maybe more appropriate in some cases.

        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/

Upvotes: 2

ngocld
ngocld

Reputation: 151

You use short format:

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

Upvotes: 2

OLC
OLC

Reputation: 31

A scriptblock string should match the format as "{ ... }".Use the follow code will be ok:

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

Upvotes: 3

NullPointer
NullPointer

Reputation: 2184

Ah, the parameter to ScriptBlock itself needs to be of type ScriptBlock.

full code:

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
}

Putting the answer here if someone finds it useful in the future

Upvotes: 16

Related Questions