Powershell命令处理(传入变量)

时间:2009-04-30 22:04:52

标签: command-line powershell parameters arguments command

我正在创建一个Powershell脚本来部署一些代码,部分过程是调用名为RAR.EXE的命令行压缩工具来备份一些文件夹。

我正在尝试动态构建参数,然后让PowerShell用变量调用命令但是我遇到了麻烦。它不起作用......

运行以下脚本,您应该看到我在说什么。作为变量传入的参数正在被破坏。如果我传递整个命令+参数,我得到臭名昭着的“不被识别为cmdlet ...”的消息。

感谢您的帮助!

echo "this should succeed"
& cmd /c echo foo

echo "why does this echo out an additional double quote?"
$param = "/c echo foo"
& cmd "$param"

echo "this does the same"
$param = "/c echo foo"
& cmd $param

echo "escaping the slash doesn't work either..."
$param = "`/c echo foo"
& cmd $param

echo "this fails, but why?"
$cmd = "cmd /c echo foo"
&$cmd

6 个答案:

答案 0 :(得分:9)

呼叫运营商'&'在这种情况下是不必要的。它用于在新范围内调用命令。这通常用于调用由字符串或sc​​riptblock指定的命令。它还有另一个好处,即在命令完成后,在PowerShell脚本中创建的任何变量都会被丢弃,并且范围消失。

然而,由于cmd是一个EXE,它在一个完全不同的过程中执行。 FWIW,您可以直接从cmd.exe获得类似的输出:

> cmd "/c echo foo"
foo"

所以最后的额外引用是cmd.exe问题。通常,当PowerShell执行解析以调用命令时,您需要将命令与参数分开。例如

45> & { $foo = "foo" }
46> $foo  # Note that $foo wasn't found - it went away with the scope
47> . { $foo = "foo" } # dotting executes in the current scope
48> $foo 
foo

这里值得注意的例外是Invoke-Expression的行为类似于“评估此字符串”功能。如果用户提供字符串,请小心使用,尤其。如果他们提供了“ri C:\ -r”,那么你的日子会很糟糕。

在这种情况下,正如其他人所建议的那样,我会将/ c拉出字符串$ param字符串并指定它,例如:

cmd /c $param

或者使用Invoke-Expression但要小心使用。 BTW当您尝试调试从PowerShell向EXE发送参数的问题时,请查看PowerShell社区扩展(http://pscx.codeplex.com)中的echoargs实用程序。它非常方便:

49> $param = "/c echo foo"
50> echoargs $param
Arg 0 is </c echo foo>

这表明cmd.exe接收“/ c echo foo”作为单个参数。 “/ c”应该是“echo foo”(要执行的命令)的单独参数。

答案 1 :(得分:8)

我和&amp;在尝试调用您正在尝试的可执行类型命令时,过去调用运算符。不确定我理解为什么。然而,Invoke-Expression似乎总是在这种情况下起作用:

PS C:\> $cmd = "cmd /c echo foo"
PS C:\> Invoke-expression $cmd
foo

答案 2 :(得分:8)

我发现这样做的另一种方法是为命令行创建一个参数数组,并将其与apersand&amp;呼叫运营商。像这样:

$exe = "cmd";
[Array]$params = "/c", "echo", "foo";

& $exe $params;

这对我有用。

我最初在这里发现了这种技术: http://techstumbler.blogspot.com/2009/12/windows-commands-with-arguments-in.html

答案 3 :(得分:3)

你失败的最后一个例子,因为“&amp;”将字符串视为一个参数,因此它正在查找名为“cmd / c echo foo.exe”的程序。 :)

这有效:

& $cmd $params

至于双引号问题,看起来cmd似乎不喜欢PowerShell提出的参数引用。它得到了这个:

cmd "/c echo foo"

所以我认为它将/ c之后的所有内容都视为确切的命令,所以就像这样:

echo foo"

一些命令行程序和命令行的时髦解析(这就是PowerShell为函数和cmdlet接管此作业的原因)。在cmd的情况下,我建议:

$param = "echo foo"
& cmd /c $param

答案 4 :(得分:0)

我认为这是使用cmd / c的工件。运行

$param = "echo foo"
cmd /c $param

工作正常。除非你有一个真实的代码示例,否则有点难以拍摄。

答案 5 :(得分:0)

当Args包含在String中时,它们的处理方式不同:

PS D:\> echo "1 2 3"
1 2 3
PS D:\> echo 1 2 3
1
2
3

当您为args使用变量时会出现相同的结果:

PS D:\> $param = "1 2 3"
PS D:\> echo $param
1 2 3

解决方案是使用数组:

PS D:\> $param = @(1,2,3)
PS D:\> echo $param
1
2
3