带有双引号的参数未通过ArgumentList正确传递给Scriptblock

时间:2013-02-20 20:15:22

标签: powershell powershell-remoting

我正在编写通用的powershell脚本来在远程计算机上执行部署。我遇到了一个我无法超越的问题,这个问题是由ArgumentList传递的Scriptblock中带双引号的参数

我有这样的事情:

$remoteAddress = "some-pc"
$deploymentCommand = "D:\some path\Command.exe"
$deploymentPackages = @(`"“package - one - external"`", `"“package - two - external"`", `"“package - three - internal"`")

foreach ($deploymentPackage in $deploymentPackages)
{
invoke-command -ComputerName $remoteAddress -ScriptBlock { param ($deployCmd, $deployPackage) &  $deployCmd -package:$deployPackage -action:doit } -ArgumentList   $deploymentCommand,$deploymentPackage
}

我在$ deploymentPackages中添加了双引号。而且我仍然像我一样快速执行我的命令(当然失败了):

D:\some path\Command.exe -package:package - one - external -action:doit
D:\some path\Command.exe -package:package - two - external -action:doit
D:\some path\Command.exe -package:package - three - external -action:doit

正确的执行路径应为:

D:\some path\Command.exe -package:"package - three - external" -action:doit

没有包裹周围的引号 - 一个 - 外部的每一个都搞乱了

如何超越这个问题,因为我已经测试了多个解决方案,而且没有测试过。

提前感谢您的帮助!

5 个答案:

答案 0 :(得分:8)

您可以使用单引号来包装字符串来解决此问题。使用单引号时,引号之间的内容将保持不变(变量不会扩展,并且将保留引号之类的符号)。 E.g。

PS > '"this is a test"'
"this is a test"

因此,要修复脚本,请尝试使用以下代码替换deploymentpackages数组:

$deploymentPackages = @('"package - one - external"', '"package - two - external"', '"package - three - internal"')

答案 1 :(得分:6)

你可以做这样的事情

$remoteAddress = "some-pc"
$deploymentCommand = "D:\some path\Command.exe"
$deploymentPackages = @('package - one - external', 'package - two - external', 'package - three - internal')
$remoteScript = {
    param( $deployCmd, $deployPackage )
    & $deployCmd "-package:$deployPackage" -action:doit
}

foreach ($deploymentPackage in $deploymentPackages)
{
   invoke-command -ComputerName $remoteAddress -ScriptBlock $remoteScript -ArgumentList $deploymentCommand,$deploymentPackage
}

-package:<some string here>捆绑到一个参数传递给您的可执行文件时,这与在cmd.exe中执行-package:"aaa bbb ccc"之类的操作相同。

我假设您不希望将文字引号传递给exe,只是-package:<some string here>只是一个参数,而不管<some string here>中的空格

如果您希望将文字引号传递给exe,请使用上面的代码

& $deployCmd "-package:`"$deployPackage`"" -action:doit

答案 2 :(得分:1)

尝试使用带双引号的字符串周围的单引号。我简化了脚本,只是编写字符串而不是运行它。

$remoteAddress = "some-pc";
$deploymentPackages = @('"package - one - external"', '"package - two - external"', '"package - three - internal"');

foreach ($deploymentPackage in $deploymentPackages)
{
    invoke-command -ComputerName $remoteAddress -ScriptBlock {
        param ($deploymentPackage) write-host ("-package:{0} -action:doit" -f $deploymentPackage); 
    } -ArgumentList   $deploymentPackage;
}

答案 3 :(得分:1)

使用"""。例如,

$Var = "One"

$Var将显示One

"""$Var"""会显示One

答案 4 :(得分:0)

尝试从DOS脚本调用的PowerShell脚本发送电子邮件时遇到了同样的问题。我找不到下面的解决方案了。

DOS脚本

set MSG="US-TrackingFile has been copied to Z: drive"
call SendMail.bat %MSG%

SendMail.bat DOS脚本

PowerShell.exe .\SendMail.ps1 '"%1"'

SendMail.ps1 PowerShell脚本

$msg = $args[0]

Send-MailMessage
  -to "bernard_schleich@atos.net" 
  -subject "$msg" 
  -smtpserver emearelay.ec.company.com 
  -from "windows.system@company.com" 

以下解决方案无需调用中间DOS脚本也可以

set MSG="\"US-TrackingFile has been copied to Z: drive\""
PowerShell.exe .\SendMail.ps1 %MSG%

但有点棘手,因为你必须添加\&#34;在每条消息的开头和结尾。

在所有情况下,我的消息标题在消息的开头和结尾都没有双引号正确显示: - )