如何使用 C# 将参数传递给 PowerShell 脚本? [英] How to pass parameter to a PowerShell script using C#?

查看:118
本文介绍了如何使用 C# 将参数传递给 PowerShell 脚本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆