Передача двойных кавычек через 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"