Я хочу вызвать небольшой скрипт PowerShell (v5.1) из командной строки Windows 10 Pro с аргументами.
param($ReqURL, $JSONString)
Write-Host $ReqURL # for debug
Write-Host $JSONString # for debug
Invoke-RestMethod -Uri $ReqURL -Method Patch -ContentType "application/json" -Body $JSONString
Вызов скрипта в консоли PowerShell работает нормально:
.\http-patch.ps1 -ReqURL myRESTApi -JSONString '{"lastname": "Bunny"}'
Вызов сценария из командной строки Windows (cmd.exe
) работает, когда я избегаю двойных кавычек, например:
PowerShell .\http-patch.ps1 -ReqURL myRESTApi -JSONString '{\"lastname\": \"Bunny\"}'
Но когда я использую параметр -File
, он терпит неудачу, потому что $JSONString
внутри скрипта равен '{"lastname":
:
PowerShell -File "C:\work\LV Demo\http-patch.ps1" -ReqURL myRESTApi -JSONString '{\"lastname\": \"Bunny\"}'
Я предполагаю, что здесь есть некоторые проблемы с кавычками, но я не могу найти правильный путь.
При использовании параметра -File
в powershell.exe, интерфейсе командной строки Windows PowerShell, только двойные кавычки ("
) распознаются как имеющие синтаксическую функцию при вызове из-за пределов PowerShell, например из cmd.exe
:
Поэтому переключитесь с '
на "
(встроенные символы "
требуют экранирования как \"
(sic) в любом случае):
:: From cmd.exe
PowerShell -File "C:\work\LV Demo\http-patch.ps1" -JSONString "{\"lastname\": \"Bunny\"}" -ReqURL myRESTApi
Напротив, когда вы используете -Command
, '...'
строки распознаются после неэкранированных "
символов. - единственные с синтаксической функцией во время первоначального синтаксического анализа командной строки - были удалены, потому что полученные токены затем интерпретируются как код PowerShell.
Для получения рекомендаций о том, когда использовать -Command
и -File
, а также о различиях в результирующем синтаксическом анализе, см. этот ответ.
Изнутри PowerShell редко возникает необходимость вызывать другой экземпляр PowerShell, учитывая, что .ps1
файлы можно вызывать напрямую в процессе.
В тех случаях, когда вам нужно вызвать CLI из PowerShell — скажем, вам нужно вызвать CLI другой версии PowerShell, PowerShell (Core) pwsh.exe , из powershell.exe
или наоборот — лучший выбор использовать блок сценария ({ ... }
) (который работает только при вызове из PowerShell), потому что это:
# From PowerShell
# Note how the " chars. now need NO escaping.
# (If you were to use a "..." string, you'd escape them as `" or "")
PowerShell {
& C:\work\LV Demo\http-patch.ps1" -JSONString '{"lastname": "Bunny"}' -ReqURL myRESTApi
}
Хотя вы можете вызывать с помощью отдельных аргументов, аналогично тому, как вы должны вызывать извне PowerShell, вы не только потеряете преимущество типизированного вывода, но также столкнетесь с давней ошибкой вплоть до PowerShell 7.2.x, которая требует ручного экранирования. встроенных "
символов. как \
при вызове внешних программ - см. этот ответ - о чем свидетельствует одна из ваших собственных попыток (здесь использование '...'
вполне нормально, потому что PowerShell его распознает):
# !! Note the unexpected need to \-escape the embedded " chars.
PowerShell -File .\http-patch.ps1 -JSONString '{\"lastname\": \"Bunny\"}' -ReqURL myRESTApi
# Variant with double quotes.
# !! Note the *double* escaping: first with ` - for the sake of PowerShell itself -
# !! then with \ due to the bug.
PowerShell -File .\http-patch.ps1 -JSONString "{\`"lastname\`": \`"Bunny\`"}" -ReqURL myRESTApi
Предыстория моего вопроса заключалась в том, что я начал тестировать http-patch.ps1 непосредственно из терминала PowerShell. Рад, что это сработало, я хотел вызвать скрипт в LabVIEW VI (LabVIEW не имеет встроенного HTTP-патча VI), что было бы аналогично тому, чтобы сделать это из cmd.exe. Это пошло не так. Поэтому я начал тестировать разные комбинации и чуть не сошел с ума, обнаружив, что каждая из них ведет себя по-разному. Решение блока скриптов выглядит для меня наиболее элегантным.
Большое спасибо, это работает из терминала cmd! Просто для моего интереса: почему это не работает, когда я вызываю PowerShell из терминала PowerShell? Я получаю
JSONString = {\