Передача двойных кавычек через PowerShell + WinRM

Я использую этот код для выполнения удаленного кода (установки MSI) на сервере. Передача двойной кавычки через скрипт просто не работает. Я попробовал два варианта, как указано ниже (№ 3 и № 4) вместе с выводами.

Вход № 1 (простой случай для проверки двойных кавычек в команде)

powershell.exe -inputformat none -File client.ps1 -target 1.2.3.4 -port 5985 -password "pass" -username "user" -command "echo hello"

Выход (Работы)

hello

Вход № 2 (понятно, это не сработает)

powershell.exe -inputformat none -File client.ps1 -target 1.2.3.4 -port 5985 -password "pass" -username "user" -command "echo hello world"

Выход

hello
world

Вход № 3

powershell.exe -inputformat none -File client.ps1 -target 1.2.3.4 -port 5985 -password "pass" -username "user" -command "echo `"hello world`""

Вывод (Что случилось с другим словом?)

hello

Вход № 4

powershell.exe -inputformat none -File client.ps1 -target 1.2.3.4 -port 5985 -password "pass" -username "user" -command @'
>> echo "hello world"
>> '@
>>

Вывод (опять же, второе слово отсутствует)

hello

Если эхо работает, я смогу включить изменения в команды MSI в используемое мной основанное на Runspace использование.


Настройка MSI работает нормально, если я использую следующее. Обратите внимание на одинарные кавычки.

msiexec /qn /i 'C:\setups\My Software.msi'

Но мне нужно передать публичные свойства, и MSI не нравится в нем ни одной кавычки. Попытка выполнить следующее открывает диалог аргументов MSI.

msiexec /qn /i 'C:\setups\My Software.msi' MYPROP='My Value'

Запуск этого из локальной командной строки на сервере работает нормально.

msiexec /qn /i "C:\setups\My Software.msi" MYPROP="My Value"

2 ответа

Решение

Если вы вызываете это из cmd.exe, вам придется избегать двойных кавычек в соответствии с правилами CMD.

powershell.exe -command "echo \"hello world\""

Выход

hello world

Лично я бы рекомендовал избегать передачи параметров из командной строки, если это вообще возможно. Может быть, вы могли бы сохранить значения параметров в файле (например, сериализованный XML, JSON) и сделать так, чтобы скрипт PowerShell считывал файл?

Еще лучше, я бы предложил любую работу с процессами (например, msiexec.exe) сквозь Start-Process Командлет. Таким образом, вы можете создать ценность для -ArgumentList параметр в переменной, а затем гарантируется, что он будет проходить именно так, как вы хотите, и, кроме того, вы не будете ограничены правилами цитирования cmd.exe,

Учтите следующее:

$ArgumentList = '/package "c:\setups\My Software.msi" /passive /norestart /l*v "{0}\temp\Install My Software.log" MYPROP="My Value With Spaces"' -f $env:windir;
Start-Process -FilePath msiexec.exe -ArgumentList $ArgumentList;

Или вы можете закодировать вашу команду в виде строк base64, чтобы избежать случайного интерпретирования любых специальных символов, например, заключенных в двойные кавычки.

powershell.exe -EncodedCommand "ZQBjAGgAbwAgACIAaABlAGwAbABvACAAdwBvAHIAbABkACIA"

Результат

hello world

ZQBjAGgAbwAgACIAaABlAGwAbABvACAAdwBvAHIAbABkACIA .... является представлением base64 этого. Посмотри, как мне не нужно было ничего убегать.

echo "hello world"
Другие вопросы по тегам