Parameters with double quotes are not properly passed to Scriptblock by ArgumentList

ε祈祈猫儿з 提交于 2019-12-06 02:44:51

问题


I'm writing generic powershell script to perform deployments on remote machines. I have hit one problem I can not overrun, and this problem is with parameters with double quotes in Scriptblock passed by ArgumentList

I have something like this:

$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
}

I have added double quotes in $deploymentPackages. And still I'm getting my command executed remotly like this (which of course fails):

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

while proper execution path should be:

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

without quotes around package - one - external which mess up everythig

How to overrun this problem, because i have tested number of solutions and non of them worked.

Thanks for help in advance!


回答1:


You could do something like this

$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
}

This bundles -package:<some string here> into a single argument when passed to your executable, which is the same as doing something like -package:"aaa bbb ccc" in cmd.exe.

I assume you don't want literal quotes passed to the exe, just for -package:<some string here> to be a single argument regardless of spaces in <some string here>

If you want literal quotes to be passed to the exe, use the above code with

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



回答2:


You can fix this by using single quotes to wrap your strings. With single quotes, the content between the quotes will be untouched(variables won't expand and signs like quotes will be kept). E.g.

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

So to fix your script, try replacing your deploymentpackages array with this:

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



回答3:


Try using single quotes around the string with the double quotes. I simplified the script a little bit to just write the string instead of running it.

$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;
}



回答4:


Use """. For example,

$Var = "One"

$Var will display One.

While """$Var""" will display One




回答5:


I have encountered the same problem when trying to send an email from a PowerShell script called from a DOS script. I have lost some time to find the following solution.

DOS Script

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

SendMail.bat DOS script

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

SendMail.ps1 PowerShell script

$msg = $args[0]

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

The following solution without calling intermediary DOS script work also

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

but is a little tricky because you must add \" at start and end of each message.

In all cases, the title of my message is correctly displayed without double quote at start and end of message :-)



来源:https://stackoverflow.com/questions/14989073/parameters-with-double-quotes-are-not-properly-passed-to-scriptblock-by-argument

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!