I created a powershell script that consists of:
param($ServerName, $Location)
"Application Name: $ServerName"
"Location: $Location"
when I am in the powershell and I run .\\Params.ps1 ConsoleApp1 Washington, DC
it will display:
Application Name: ConsoleApp1
Location: Washington D.C.
So I know this works just fine. Now I am wanting to take this to c# and perform parameter passing.
In my console application, I created the following:
static void Main(string[] args)
{
string[] scriptParam = { "ConsoleApp1", "Washington, D.C."};
string powerShell = PerformScript(scriptParam);
Console.WriteLine(powerShell);
Console.WriteLine("\nPowershell script excuted!!");
Console.ReadLine();
}
static string PerformScript(string scriptParameters)
{
InitialSessionState runspaceConfiguration = InitialSessionState.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
PowerShell ps = PowerShell.Create();
ps.Runspace = runspace;
ps.AddCommand(@"C:\Users\users\source\repos\ConsoleApp1\powershell\Params.ps1");
foreach (string scriptParameter in scriptParameters)
{
ps.AddParameter(scriptParameter);
}
Collection<PSObject> psObjects = pipeline.Invoke();
runspace.Close();
StringBuilder stringBuilder = new();
foreach (PSObject item in psObjects)
{
stringBuilder.AppendLine(item.ToString());
}
return stringBuilder.ToString();
}
but when I run the program I get an Exception Unhandled
on the line
Collection<PSObject> psObjects = pipeline.Invoke();
System.Management.Automation.PSInvalidOperationException: 'The pipeline does not contain a command.'
Am I doing something incorrect when passing the parameters?
Updated code:
static string PerformScript(string[] scriptParameters)
{
InitialSessionState runspaceConfiguration = InitialSessionState.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
using (var ps = PowerShell.Create())
{
var result = ps.AddCommand(@"C:\Users\users\source\repos\ConsoleApp1\powershell\Params.ps1")
.AddArgument("ConsoleApp1")
.AddArgument("Washington, D.C.")
.Invoke();
foreach (var o in result)
{
Console.WriteLine(o);
}
}
Collection<PSObject> psObjects = pipeline.Invoke();
runspace.Close();
StringBuilder stringBuilder = new();
foreach (PSObject item in psObjects)
{
stringBuilder.AppendLine(item.ToString());
}
return stringBuilder.ToString();
}
Use .AddArgument()
, not .AddParameter()
.
What you're trying to pass are positional (unnamed) arguments, ie mere parameter values whose target parameter is implied by their position , which is what .AddArgument()
is for.
By contrast, .AddParameter()
is for named arguments, where you specify the parameter name first, followed by its value (argument).
Here's a simplified example:
using (var ps = PowerShell.Create()) {
var result = ps.AddCommand(@"C:\Users\users\source\repos\ConsoleApp1\powershell\Params.ps1")
.AddArgument("ConsoleApp1")
.AddArgument("Washington, D.C.")
.Invoke();
foreach (var o in result) {
Console.WriteLine(o);
}
}
Note: The above uses the much simplified API that is available directly via the methods of a PowerShell
instance (created with .Create()
): If automatically creating a runspace with a default session state is sufficient, there is no need for explicit creation of a runspace with RunspaceFactory.CreateRunspace()
, a session state with InitialSessionState.Create()
, and a runspace's pipeline with .CreatePipeline()
- see the bottom section for how to apply the techniques to your code.
As for what you tried :
If you mistakenly use .AddParameter()
with a single method argument only, what the PowerShell SDK does is to default the omitted parameter value to true
, so that .AddParameter('foo')
is the equivalent of passing -foo: $true
from inside PowerShell.
This works as intended only if you're passing the name of a parameter that is a switch parameter (of type System.Management.Automation.SwitchParameter
, [switch]
in PowerShell code).
Applied to your code:
static void Main(string[] args)
{
Console.WriteLine(
PerformScript(
@"C:\Users\users\source\repos\ConsoleApp1\powershell\Params.ps1",
new string[] { "ConsoleApp1", "Washington, D.C." }
)
);
}
static string PerformScript(string scriptPath, string[] scriptArguments)
{
StringBuilder stringBuilder = new();
using (var ps = PowerShell.Create())
{
ps.AddCommand(scriptPath);
foreach (var arg in scriptArguments)
{
ps.AddArgument(arg);
}
foreach (var o in ps.Invoke())
{
stringBuilder.AppendLine(o.ToString());
}
}
return stringBuilder.ToString();
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.