PowerShell: curl is an alias for Invoke-WebRequest (why -I and Unix flags break)

You typed <code>curl -I https://example.com</code> the way every README shows, and PowerShell complained about an ambiguous parameter or returned a huge object instead of headers. On Windows, <code>curl</code> is often not curl at all.

Prove it in one line

Get-Alias curl -ErrorAction SilentlyContinue
# Windows PowerShell 5.1 typically prints:
# Alias  curl -> Invoke-WebRequest

Get-Command curl* | Format-Table Name, CommandType, Source

If you see an alias, every curl … you type is rewritten to Invoke-WebRequest … before it runs. PowerShell 7 on Windows usually prefers real curl.exe when it is on PATH, but do not assume — check.

Why Unix examples explode

You typed (Unix curl)What 5.1 actually ranTypical result
curl -I https://…Invoke-WebRequest -I …Ambiguous parameter -I (matches -InFile / others)
curl -s https://…/api.jsonInvoke-WebRequest -s …Unknown / wrong parameter; or a full response object
curl -o out.zip URLAlias + -oNot the same as curl’s output file flag
curl -H "Accept: …" URLAlias + -HDoes not map to -Headers automatically
# What people usually wanted (headers only):
curl.exe -sI https://example.com

# PowerShell-native equivalent:
Invoke-WebRequest -Uri https://example.com -Method Head |
  Select-Object StatusCode, Headers

curl.exe vs the alias

# Download a file the PowerShell way
Invoke-WebRequest -Uri https://example.com/file.zip -OutFile .\file.zip

# Same with real curl
curl.exe -fsSL -o file.zip https://example.com/file.zip

JSON APIs: prefer Invoke-RestMethod

Invoke-WebRequest gives you a response object (.StatusCode, .Content, .Headers). For JSON APIs, Invoke-RestMethod parses the body into objects automatically:

# Pretty-print JSON from an API (PowerShell)
Invoke-RestMethod -Uri https://api.oddlathe.com/v1/uuid?n=2 |
  ConvertTo-Json -Depth 5

# Real curl + pipe to a formatter elsewhere
curl.exe -s "https://api.oddlathe.com/v1/uuid?n=2"

Paste awkward JSON into the JSON formatter when a terminal dump is hard to read. Encode query strings safely with the URL encoder before you stick them on a curl line.

Inspect a link without fetching it

When you only need to understand a URL (host, path, lookalike characters, sketchy query params), you do not need curl at all:

curl.exe -sG https://api.oddlathe.com/v1/url/inspect \
  --data-urlencode "url=https://example.com/path?q=1"

Related

&& is not a valid statement separator · Running scripts is disabled · Unexpected token in JSON · TypeError: fetch failed · JSON formatter · URL encoder · Anvil URL inspect

Questions

Why does curl -I fail in PowerShell?

On Windows PowerShell 5.1, curl is an alias for Invoke-WebRequest, so -I is not the Unix "headers only" flag. Call curl.exe -sI or use Invoke-WebRequest -Method Head.

How do I run the real curl on Windows?

Type curl.exe (with the .exe). That skips the PowerShell alias. Confirm with Get-Command curl.exe.

What is the PowerShell equivalent of curl for JSON?

Invoke-RestMethod -Uri https://… parses JSON into objects. Invoke-WebRequest keeps the raw .Content string.

Is wget also broken?

In Windows PowerShell 5.1, wget is also an alias for Invoke-WebRequest. Use wget.exe if you installed a real one, or stick to Invoke-WebRequest / curl.exe.

Does PowerShell 7 still alias curl?

Often no — pwsh prefers curl.exe when present — but check Get-Alias curl. Writing curl.exe is always unambiguous.

Published .

Try it

Related guides

Newest guides