如何使用 C# 将参数传递给 PowerShell 脚本? [英] How to pass parameter to a PowerShell script using C#?
问题描述
我正在尝试使用 C#
我的脚本需要参数才能运行,否则会抛出错误.
My script requires parameters to run otherwise, it'll throw an error.
这是我的脚本的精简版
param ($url)
if ($url -eq $null) {
throw "No Url was provided"
}
write-host "$url was the provided value"
现在,使用 C#
我正在尝试按如下方式执行脚本
Now, using C#
I am trying to execute the script as follow
try {
var defaultSessionState = InitialSessionState.CreateDefault();
defaultSessionState.ExecutionPolicy = Microsoft.PowerShell.ExecutionPolicy.Unrestricted;
using PowerShell ps = PowerShell.Create(defaultSessionState);
ps.AddScript(@"d:\test.ps1");
ps.AddParameter("url", "http://example.com/test/");
ps.Runspace.SessionStateProxy.SetVariable("ErrorActionPreference", "stop");
}
catch (Exception e) {
}
但我不断收到No Url was provided
错误.如何正确地将参数传递给我的脚本,以及如何访问它?
But I keep getting No Url was provided
error. How can I correctly pass the parameter to my script, and how to access it?
推荐答案
Mathias R. Jessen 的有用回答提供了一个有效的解决方案,但让我扩展一下解释:
Mathias R. Jessen's helpful answer provides an effective solution, but let me expand on the explanation:
PowerShell SDK 的 .AddScript()
方法 的命名有点糟糕,因为它不执行脚本文件,而是任意PowerShell 片段代码.也就是说,它期望的是一个包含整个 PowerShell 语句 的字符串,换句话说:脚本文件的内容 - 而不是脚本文件的路径.
The PowerShell SDK's .AddScript()
method is somewhat poorly named in that it doesn't execute a script file, but an arbitrary piece of PowerShell code. That is, what it expects is a string containing entire PowerShell statements, in other words: the contents of a script file - not the script file's path.
鉴于在 PowerShell 中一段可重用的代码被表示为一个脚本块,类似 .AddScriptBlock()
的名称将是一个不太容易混淆的名称(但请注意,当您调用 .AddScript()
时,您必须不要将包含要在 { ... }
中执行的语句的字符串括起来>).[1]
Given that in PowerShell a piece of reusable code is represented as a script block, something like .AddScriptBlock()
would be a less confusing name (though note that you must not enclose the string containing the statements to execute in { ... }
when you call .AddScript()
).[1]
Mathias 的回答显示了 .AddCommand()
是正确的使用方法,因为 PowerShell 中的 command 是任何可以直接执行的东西:别名、函数、cmdlet、外部可执行文件 - 以及脚本文件.
Mathias's answer shows how .AddCommand()
is the right method to use, because a command in PowerShell is anything that represents something that can be directly executed: aliases, functions, cmdlets, external executables - and also script files.
至于你尝试了什么:
String d:\test.ps1
被解释为一段 PowerShell 代码(就像你在命令行提交这个字符串一样).该代码碰巧调用了一个脚本文件,但是没有参数.
也就是说,您的脚本被调用,但没有您通过 .AddParameter()
添加的参数.
String d:\test.ps1
is interpreted as a piece of PowerShell code (the same way it would be if you submitted this string on the command line). That code happens to call a script file, but does so without arguments.
That is, your script was called, but without the parameter you added via .AddParameter()
.
- 还要注意,如果脚本路径碰巧包含空格或嵌入的变量引用,则必须使用嵌入引用并通过
&
调用结果,呼叫运营商;例如,.AddScript(@".'d:\test 1.ps1'");
- 请参阅这个答案 到一个密切相关的问题以了解详细信息.
- Also note that if the script path happened to contain spaces or embedded variable references, you'd have to use embedded quoting and call the result via
&
, the call operator; e.g.,
.AddScript(@". 'd:\test 1.ps1'");
- see this answer to a closely related question for details.
但是,请注意,您的 .AddParameter()
调用在技术上仍然有效,但是接收参数的是 脚本块整体,而不是(一个)里面的语句 - 对d:\test.ps1
的调用.
However, note that your .AddParameter()
call technically still worked, but it was the script block as a whole that received the parameter, not the (one) statement inside it - the call to d:\test.ps1
.
从技术上讲,可以通过splatting 自动$args
变量(在其中收集所有参数,在没有显式参数声明的情况下,通过一个 param(...)
块):
Technically, it would have been possible to relay the arguments to the script-file invocation, by way of splatting the automatic $args
variable (in which all arguments are collected, in the absence of explicit parameter declarations via a param(...)
block):
ps.AddScript(@"d:\test.ps1 @args");
也就是说,如果您的代码所做的只是调用单个脚本文件(带参数),那么 .AddCommand()
解决方案既简单又高效;此外,它还避免了执行机器的 PowerShell 执行策略,只有.AddScript()
添加的语句受制于.
That said, if all your code does is to invoke a single script file (with arguments), the .AddCommand()
solution is both simpler and more efficient; additionally, it avoids potential problems with the executing machine's PowerShell execution policy, which only .AddScript()
-added statements are subject to.
[1] .AddScript("...")
,用 PowerShell 代码表示,有效地执行以下操作:
<代码>.{ ... }
也就是说,它将字符串解析为脚本块,并通过 .
、dot-sourcing 运算符(稍后调用 .Invoke()
时).
[1] .AddScript("...")
, expressed in PowerShell code, effectively does the following:
. { ... }
That is, it parses the string as a script block, and executes it via .
, the dot-sourcing operator (when .Invoke()
is later called).
这篇关于如何使用 C# 将参数传递给 PowerShell 脚本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!