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
Doug Finke
6,8432 gold badges34 silver badges48 bronze badges
-
This seems to indicate that .AddParameter("p", 1) should work.Mike Shepard– Mike Shepard2012年07月10日 02:01:01 +00:00Commented Jul 10, 2012 at 2:01
-
Yeah, agreed. So far it doesn't pass through to the script.Doug Finke– Doug Finke2012年07月10日 02:06:58 +00:00Commented Jul 10, 2012 at 2:06
-
You've probably found this, where Don Jones uses it and adds a scriptblock parameterMike Shepard– Mike Shepard2012年07月10日 02:15:05 +00:00Commented 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.Doug Finke– Doug Finke2012年07月10日 02:22:03 +00:00Commented Jul 10, 2012 at 2:22
3 Answers 3
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
Elijah W. Gagne
2,8414 gold badges33 silver badges29 bronze badges
Sign up to request clarification or add additional context in comments.
6 Comments
Mike Shepard
I'm not seeing how you passed any parameters to a script.
Elijah W. Gagne
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)Mike Shepard
Wasn't my question, just something I'm interested in and happened to see your answer after it was posted.
Doug Finke
That works for strings. What if I want to pass in an instance of class?
Doug Finke
Yup, the difference is. I was using AddScript. Your example uses AddCommand. This lets AddParameter be used as well.
|
So, to make a long answer short: Use AddCommand instead of AddScript
answered Mar 11, 2015 at 14:34
Willem M.
5341 gold badge5 silver badges8 bronze badges
Comments
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
Leblanc Meneses
3,0911 gold badge25 silver badges29 bronze badges
1 Comment
user2838376
Actually, the best way to do it!
lang-bash