新しもの好きプログラマの耳より情報ブログ

仕事でもあるプログラミングについて役に立ちそうな情報を発信していこうというブログです。役に立たなそうな情報はfacebookで。

PowerShellのパラメータに&(アンパサンド)が入ったURLなどを渡す方法

概要

WebhookのURLに&(アンパサンド)が入っていることがあるが、これをPowerShellのコマンドのパラメータに渡そうとすると、そのままではエラーになる。これの解決方法を調べた。

結論

3つの"(ダブルクォート)でURLを囲めば良い。もしくは、'(シングルクォート)と"(ダブルクォート)でURLを囲めば良い。

例:

  1. """https://xxx/yyy?param1=value1&param2=value2"""
  2. '"https://xxx/yyy?param1=value1&param2=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&param2=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&param2=value2"""

おそらく、PowerShellのパラメータ解決の順序の都合ではないか。1つだけの""だとパラメータの区切り(スペースでの区切り)を判断する時に解決されて消えてしまうので、&がそのまま残る。そこにもう1つの""があれば、引き続き文字列として解釈される。""の中の"はエスケープする必要があるので、結果としては3つの"(ダブルクォート)で囲む必要がある。ということだと思う。実際、代わりに'""'のようにシングル・ダブルクォートで囲んでも成功した。

ちなみに、PowerShellではなくコマンドプロンプトで実行すればこの問題は起きない。今回は実行環境をWindowsで標準となりつつあるPowerShellに揃えたくて、そのやり方を調べた。こんな面倒な書き方をしたくない人は、コマンドプロンプトで実行しても良いと思う。