概要
WebhookのURLに&(アンパサンド)が入っていることがあるが、これをPowerShellのコマンドのパラメータに渡そうとすると、そのままではエラーになる。これの解決方法を調べた。
結論
3つの"(ダブルクォート)でURLを囲めば良い。もしくは、'(シングルクォート)と"(ダブルクォート)でURLを囲めば良い。
例:
"""https://xxx/yyy?param1=value1¶m2=value2"""
'"https://xxx/yyy?param1=value1¶m2=value2"'
経緯など
PowerShellでaz vm auto-shutdownにWebhookのURLを渡そうとしたところ、&(アンパサンド)を文字列として渡せなくて困った。単純に""(ダブルクォート2つの二重引用符)で囲んだだけだと、コード実行の&と認識されてしまう。
ダメな例
az vm auto-shutdown --time 0000 --name VMName --resource-group ResourceGroupName --subscription SubscriptionName --webhook "https://xxx/yyy?param1=value1¶m2=value2"
この場合--webhookのパラメータは「https://xxx/yyy?param1=value1」と認識され、次のエラーが出る。
'param2' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
PowerShellで&などの特殊文字をエスケープするには `
(バッククォート)を使えば良いという情報があるが、&を全て`&に置き換えても結果は変わらず。
次のサイトを参考に、3つの"(ダブルクォート)でURLを囲んだところ、成功した。
powershell — コマンドラインのPowerShellパラメータでアンパサンド、セミコロン、中括弧をエスケープする方法は?
成功例
az vm auto-shutdown --time 0000 --name VMName --resource-group ResourceGroupName --subscription SubscriptionName --webhook """https://xxx/yyy?param1=value1¶m2=value2"""
おそらく、PowerShellのパラメータ解決の順序の都合ではないか。1つだけの""だとパラメータの区切り(スペースでの区切り)を判断する時に解決されて消えてしまうので、&がそのまま残る。そこにもう1つの""があれば、引き続き文字列として解釈される。""の中の"はエスケープする必要があるので、結果としては3つの"(ダブルクォート)で囲む必要がある。ということだと思う。実際、代わりに'""'のようにシングル・ダブルクォートで囲んでも成功した。
ちなみに、PowerShellではなくコマンドプロンプトで実行すればこの問題は起きない。今回は実行環境をWindowsで標準となりつつあるPowerShellに揃えたくて、そのやり方を調べた。こんな面倒な書き方をしたくない人は、コマンドプロンプトで実行しても良いと思う。