PowerShell で curl のオプションが効かない(Invoke-WebRequest の別名)
Windows PowerShell 5.1 では curl は Invoke-WebRequest の別名で、-I や -o といった本家のオプションを解釈しない。
curl.exe と拡張子まで書いて呼ぶか、cmdlet 側のパラメータに読み替える。
公開:
要約
Windows PowerShell 5.1 の curl は本家の curl ではない。Invoke-WebRequest のリファレンス(新しいタブで開く) が「Windows PowerShell includes the following aliases」として iwr / curl / wget を挙げているとおり、cmdlet への別名である。
PS> curl -I https://example.com
Invoke-WebRequest : Cannot process command because of one or more missing mandatory parameters: Uri.-I はヘッダのみ取得する curl のオプションだが、PowerShell はこれをパラメータ名の前方一致として扱い -InFile に結び付ける。
続く URL はそのファイル名として吸われるため、位置引数の -Uri が埋まらず、URL を渡したはずなのに「Uri が無い」と言われる。
よくある原因
- 別名の優先度: PowerShell は同名の別名と実行ファイルがあれば別名を先に選ぶ。
Windows 10 以降にはC:\Windows\System32\curl.exeが同梱されているが、curlと打つ限りそちらは呼ばれない。 - 前方一致でパラメータに化ける: PowerShell はパラメータ名の省略を前方一致で解決する。
-Iは-InFileに一致してしまうので、存在しないオプションを渡したときのような「そんなパラメータは無い」というエラーにはならない。-Qのようにどれにも一致しない場合だけ別のメッセージが出る。
原因の切り分けが遅れやすい。 - 手順書の使い回し: Linux / macOS 向けの
curl -sSL ... | shのような 1 行を、そのまま PowerShell の窓へ貼っている。 - バージョン差: PowerShell 7 系にこの別名は無く、
curlは素直にcurl.exeへ解決される。
7 で検証した手順が 5.1 で落ちる。 - 解析の既定が変わった: 2025 年 12 月のセキュリティ更新(CVE-2025-54100)以降、5.1 の
Invoke-WebRequestは-UseBasicParsingを付けないと確認プロンプトを出す。
スクリプトの中では応答できず、そこで止まる。
解決策
1. curl.exe と書く
curl.exe -I https://example.com
curl.exe -sSL -o out.zip https://example.com/file.zip拡張子まで書けば別名は当たらず、本家の curl がそのまま動く。
手順書を移植するときはこれが最短である。
2. いま何に解決されているか確かめる
Get-Command curl | Format-List Name, CommandType, DefinitionName : curl
CommandType : Alias
Definition : Invoke-WebRequestCommandType が Alias なら別名、Application なら実行ファイルである。
5.1 と 7 のどちらで動かしているかを推測せずに済む。
3. cmdlet のパラメータへ読み替える
Invoke-WebRequest -Uri https://example.com -Method Head -UseBasicParsing
Invoke-WebRequest -Uri https://example.com/file.zip -OutFile out.zip -UseBasicParsing-I は -Method Head、-o は -OutFile に対応する。
5.1 では -UseBasicParsing も付けて、確認プロンプトを避ける。
4. 別名を外す
Remove-Item Alias:curlそのセッションでだけ別名が消え、curl が curl.exe へ解決されるようになる。Remove-Alias は PowerShell 6.0 で追加された cmdlet なので、5.1 では上の書き方を使う。
5. スクリプトでは名前を固定する
共有するスクリプトに curl とだけ書くと、実行者のバージョンで意味が変わる。curl.exe か Invoke-WebRequest のどちらかに寄せておけば、この曖昧さは残らない。