Calling PowerShell From C#
Solution 1
A little bit late but:
PowerShell ps = PowerShell.Create();
ps.Runspace.SessionStateProxy.SetVariable("a", new int[] { 1, 2, 3 });
ps.AddScript("$a");
ps.AddCommand("foreach-object");
ps.AddParameter("process", ScriptBlock.Create("$_ * 2"));
Collection<PSObject> results = ps.Invoke();
foreach (PSObject result in results)
{
Console.WriteLine(result);
}
returns:
2
4
6
Solution 2
I have done my research and PowerShell.Invoke( IEnumerable )
will set the InputObject
of the first command in the list. Therefore instead of setting InputObject
on inputCmd
above, we can instead pass it through the Invoke
method. We still need the first ForEach-Object
call to pass the input array to.
Comments
-
Tahir Hassan almost 2 years
I am using
System.Management.Automation
DLL which allows me to call PowerShell within my C# application like so:PowerShell.Create().AddScript("Get-Process").Invoke();
What I am trying to do is call PowerShell but supply the input list. For example, in:
1, 2, 3 | ForEach-Object { $_ * 2 }
I am trying to supply the left hand side
1, 2, 3
when invoking:// powershell is a PowerShell Object powershell.Invoke(new [] { 1, 2, 3 });
However this does not work. The workaround I came up with was using
ForEach-Object
and then passing the array as anInputObject
with the{ $_ }
as theProcess
:// create powershell object var powershell = PowerShell.Create(); // input array 1, 2, 3 Command inputCmd = new Command("ForEach-Object"); inputCmd.Parameters.Add("InputObject", new [] { 1, 2, 3 }); inputCmd.Parameters.Add("Process", ScriptBlock.Create("$_")); powershell.Commands.AddCommand(inputCmd); // ForEach-Object { $_ * 2 } Command outputCmd = new Command("ForEach-Object"); outputCmd.Parameters.Add("Process", ScriptBlock.Create("$_ * 2")); powershell.Commands.AddCommand(outputCmd); // invoke var result = powershell.Invoke();
Although the above is working code is there any way of using
Invoke
passing in the input array because I would have though that this would be desirable way of calling it? -
Tahir Hassan over 11 yearsThis works but you are passing
1,2,3
as a string rather than an array i.e.new int[] { 1,2,3 }
. The second one is needed if I am to pass structured data to the pipeline. -
CB. over 11 years@TahirHassan The only way I know to pass .net object created is using
SessionStateProxy.SetVariable(string name, object value)
. Look at my edited answer. -
Tahir Hassan over 11 yearsYou have answered my question on how to start the pipeline with an array (without passing it to
ForEach-Object
using theInputObject
parameter as described in my question). Thanks. -
CB. over 11 years@TahirHassan Glad to help!
-
t3chb0t almost 7 yearsThis is genius! I would never look for it there!