[英]Passing parameters from c# to powershell script
我创建了一个 powershell 脚本,其中包括:
param($ServerName, $Location)
"Application Name: $ServerName"
"Location: $Location"
当我在 powershell 中运行.\\Params.ps1 ConsoleApp1 Washington, DC
,它将显示:
Application Name: ConsoleApp1
Location: Washington D.C.
所以我知道这很好用。 现在我想把它带到 c# 并执行参数传递。
在我的控制台应用程序中,我创建了以下内容:
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();
}
但是当我运行程序时,我在线上得到一个Exception Unhandled
Collection<PSObject> psObjects = pipeline.Invoke();
System.Management.Automation.PSInvalidOperationException: '管道不包含命令。'
传递参数时我做错了什么吗?
更新代码:
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();
}
使用.AddArgument()
,而不是.AddParameter()
。
您试图传递的是位置(未命名)参数,即仅仅是其目标参数由它们的位置隐含的参数值,这就是.AddArgument()
的用途。
相比之下, .AddParameter()
用于命名参数,您首先指定参数名称,然后是其值(参数)。
这是一个简化的示例:
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);
}
}
注:以上用途大大简化的API,可直接通过的方法PowerShell
实例(与创建.Create()
如果自动创建一个默认的会话状态的运行空间就足够了,没有必要进行明确的创建与运行空间RunspaceFactory.CreateRunspace()
与会话状态InitialSessionState.Create()
以及运行空间与管道.CreatePipeline()
-见如何将技术应用到你的代码底部。
至于你尝试了什么:
如果您错误地仅将.AddParameter()
与单个方法参数一起使用,PowerShell SDK 所做的就是将省略的参数值默认为true
,因此.AddParameter('foo')
相当于传递-foo: $true
from在 PowerShell 中。
仅当您传递的参数名称是开关参数(类型为System.Management.Automation.SwitchParameter
,PowerShell 代码中的[switch]
)时,这才按预期工作。
应用于您的代码:
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();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.