14

From the command line I can do.

.\test.ps1 1

How do I pass the parameter when doing this from C#? I've tried

 .AddArgument(1)
 .AddParameter("p", 1)

And I have tried passing values in as IEnumerable<object> in the .Invoke() but $p does not get the value.

namespace ConsoleApplication1
{
 using System;
 using System.Linq;
 using System.Management.Automation;
 class Program
 {
 static void Main()
 {
 // Contents of ps1 file
 // param($p)
 // "Hello World ${p}"
 var script = @".\test.ps1";
 PowerShell
 .Create()
 .AddScript(script)
 .Invoke().ToList()
 .ForEach(Console.WriteLine);
 }
 }
}
asked Jul 10, 2012 at 1:18
4
  • This seems to indicate that .AddParameter("p", 1) should work. Commented Jul 10, 2012 at 2:01
  • Yeah, agreed. So far it doesn't pass through to the script. Commented Jul 10, 2012 at 2:06
  • You've probably found this, where Don Jones uses it and adds a scriptblock parameter Commented Jul 10, 2012 at 2:15
  • Yeah, that's a bit different. If I called test.ps from the cmdline i could do .\test.ps1 (new-object PSObject). I'm trying to figure out how to do that in code. Commented Jul 10, 2012 at 2:22

3 Answers 3

10

How's this?

static void Main()
{
 string script = @"C:\test.ps1 -arg 'hello world!'";
 StringBuilder sb = new StringBuilder();
 PowerShell psExec = PowerShell.Create();
 psExec.AddScript(script);
 psExec.AddCommand("out-string");
 Collection<PSObject> results;
 Collection<ErrorRecord> errors;
 results = psExec.Invoke();
 errors = psExec.Streams.Error.ReadAll();
 if (errors.Count > 0)
 {
 foreach (ErrorRecord error in errors)
 {
 sb.AppendLine(error.ToString());
 }
 }
 else
 {
 foreach (PSObject result in results)
 {
 sb.AppendLine(result.ToString());
 }
 }
 Console.WriteLine(sb.ToString());
}

Here's a similar version that passes an instance of a DateTime

static void Main()
{
 StringBuilder sb = new StringBuilder();
 PowerShell psExec = PowerShell.Create();
 psExec.AddCommand(@"C:\Users\d92495j\Desktop\test.ps1");
 psExec.AddArgument(DateTime.Now);
 Collection<PSObject> results;
 Collection<ErrorRecord> errors;
 results = psExec.Invoke();
 errors = psExec.Streams.Error.ReadAll();
 if (errors.Count > 0)
 {
 foreach (ErrorRecord error in errors)
 {
 sb.AppendLine(error.ToString());
 }
 }
 else
 {
 foreach (PSObject result in results)
 {
 sb.AppendLine(result.ToString());
 }
 }
 Console.WriteLine(sb.ToString());
}
answered Jul 10, 2012 at 1:44
Sign up to request clarification or add additional context in comments.

6 Comments

I'm not seeing how you passed any parameters to a script.
I understand your question now. I've updated my answer to show a script and passing an argument to it. The easiest way I know to do it is to include the arguments in string you pass psExec.AddScript(script)
Wasn't my question, just something I'm interested in and happened to see your answer after it was posted.
That works for strings. What if I want to pass in an instance of class?
Yup, the difference is. I was using AddScript. Your example uses AddCommand. This lets AddParameter be used as well.
|
4

So, to make a long answer short: Use AddCommand instead of AddScript

answered Mar 11, 2015 at 14:34

Comments

3

another way is to fill the runspace with variables.

 public static string RunPs1File(string filePath, Dictionary<string, object> arguments)
 {
 var result = new StringBuilder();
 using (Runspace space = RunspaceFactory.CreateRunspace())
 {
 space.Open();
 foreach (KeyValuePair<string, object> variable in arguments)
 {
 var key = new string(variable.Key.Where(char.IsLetterOrDigit).ToArray());
 space.SessionStateProxy.SetVariable(key, variable.Value);
 }
 string script = System.IO.File.ReadAllText(filePath);
 using (PowerShell ps1 = PowerShell.Create())
 {
 ps1.Runspace = space;
 ps1.AddScript(script);
 var psOutput = ps1.Invoke();
 var errors = ps1.Streams.Error;
 if (errors.Count > 0)
 {
 var e = errors[0].Exception;
 ps1.Streams.ClearStreams();
 throw e;
 }
 foreach (var line in psOutput)
 {
 if (line != null)
 {
 result.AppendLine(line.ToString());
 }
 }
 }
 }
 return result.ToString();
 }
answered Oct 17, 2012 at 19:24

1 Comment

Actually, the best way to do it!

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.