Параметры с двойными кавычками неправильно передаются в скрипт-блок 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%
но это немного сложно, потому что вы должны добавить \"в начале и конце каждого сообщения.
Во всех случаях заголовок моего сообщения отображается правильно без двойной кавычки в начале и конце сообщения:-)