如何为System.Management.Automation.PowerShell脚本传递参数?
正确为C#中PowerShell脚本传递参数的方法
你的问题出在错误地将CommandParameter对象传递给AddScript的AddParameters方法上——CommandParameter是为AddCommand(调用外部命令/脚本文件路径)设计的,而AddScript执行的是脚本字符串,它的AddParameters接收的是参数值的集合,不是CommandParameter实例。这也是为什么你看到输出里是对象类型名而不是预期的参数值。
这里有两种可靠的解决方案:
方案一:使用AddCommand调用脚本文件(推荐)
这种方式更符合PowerShell的原生调用逻辑,能正确处理命名参数和开关参数:
using (PowerShell ps = PowerShell.Create()) { // 直接传入脚本文件路径,而不是读取内容 ps.AddCommand(pathToPS1); // 逐个添加命名参数 ps.AddParameter("Arg1", "Bla 1"); ps.AddParameter("Arg2", "Bla 2"); ps.AddParameter("ArgParamless"); // 开关参数无需传值 ps.Invoke(); }
如果想批量添加参数,也可以用CommandParameter列表配合AddParameters:
List<CommandParameter> paramList = new List<CommandParameter> { new CommandParameter("Arg1", "Bla 1"), new CommandParameter("Arg2", "Bla 2"), new CommandParameter("ArgParamless") }; using (PowerShell ps = PowerShell.Create()) { ps.AddCommand(pathToPS1); ps.AddParameters(paramList); ps.Invoke(); }
方案二:如果必须使用AddScript(读取脚本内容)
如果因为某些原因必须读取脚本内容用AddScript执行,可以通过两种方式传递参数:
方式A:位置参数传递
直接传递参数值数组,脚本的param块会按顺序接收:
string command = File.ReadAllText(pathToPS1); using (PowerShell ps = PowerShell.Create()) { ps.AddScript(command); // 按param块定义的顺序传值,开关参数传true/false ps.AddParameters(new object[] { "Bla 1", "Bla 2", true }); ps.Invoke(); }
方式B:命名参数传递
把脚本包装成自执行块,然后通过命名参数传递(更清晰,适合参数多的场景):
string command = $"& {{{File.ReadAllText(pathToPS1)}}} -Arg1 'Bla 1' -Arg2 'Bla 2' -ArgParamless"; using (PowerShell ps = PowerShell.Create()) { ps.AddScript(command); ps.Invoke(); }
为什么原来的代码会出错?
当你用AddScript加载脚本字符串后,调用AddParameters传入CommandParameter列表时,PowerShell并没有把这些对象解析为参数定义,而是直接将CommandParameter实例本身作为值传递给脚本的param变量。所以:
$Arg1和$Arg2收到的是CommandParameter对象,输出时显示其类型名$ArgParamless是开关参数,因为没有收到有效的开关触发,所以值为False
内容的提问来源于stack exchange,提问作者user2838376
相关产品推荐
相关产品推荐

