Параметры с двойными кавычками неправильно передаются в скрипт-блок ArgumentList

Я пишу универсальный сценарий PowerShell для развертывания на удаленных компьютерах. Я столкнулся с одной проблемой, которую не могу переполнить, и эта проблема связана с параметрами с двойными кавычками в Scriptblock, переданными ArgumentList

У меня есть что-то вроде этого:

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

Я добавил двойные кавычки в $ deployPackages. И все же я получаю мою команду, выполненную в некотором роде, вот так (что, конечно, не получается):

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 ответов

Решение

Вы могли бы сделать что-то вроде этого

$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> в один аргумент при передаче в ваш исполняемый файл, что аналогично выполнению чего-то вроде -package:"aaa bbb ccc" в cmd.exe.

Я предполагаю, что вы не хотите, чтобы буквальные кавычки передавались в exe, только для -package:<some string here> быть единственным аргументом независимо от пробелов в <some string here>

Если вы хотите, чтобы буквенные кавычки передавались в exe, используйте приведенный выше код с

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

Вы можете исправить это, используя одинарные кавычки для переноса строк. При использовании одинарных кавычек содержимое между кавычками не будет затронуто (переменные не будут расширяться, а такие знаки, как кавычки, будут сохраняться). Например

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

Чтобы исправить ваш скрипт, попробуйте заменить ваш deploymentpackages массив с этим:

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

Попробуйте использовать одинарные кавычки вокруг строки с двойными кавычками. Я немного упростил скрипт, чтобы просто написать строку вместо ее запуска.

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

Использование """, Например,

$Var = "One"

$Var будет отображать One,

В то время как """$Var""" будет отображать One

Я столкнулся с той же проблемой при попытке отправить электронное письмо из сценария PowerShell, вызываемого из сценария DOS. Я потерял некоторое время, чтобы найти следующее решение.

DOS Script

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

DOS-скрипт SendMail.bat

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%

но это немного сложно, потому что вы должны добавить \"в начале и конце каждого сообщения.

Во всех случаях заголовок моего сообщения отображается правильно без двойной кавычки в начале и конце сообщения:-)

Другие вопросы по тегам