Skip to content
shellmap

invoke-webrequestPowerShell's HTTP cmdlet — the curl / wget equivalent across all 5 shells

Equivalents in every shell

Bashunix
curl https://example.com

`curl` writes the response body to stdout by default. Common flags: `-L` follows redirects, `-o file` writes to disk, `-X POST -d 'key=val'` posts form data, `-H 'Content-Type: application/json' -d '{}'` posts JSON. `wget url` is the alternative; wget defaults to writing the response to a file with the URL's tail as the name.

Zshunix
curl https://example.com

Same external `curl`. macOS ships curl linked against the system Secure Transport TLS stack (different trust roots than Linux's OpenSSL builds); newer macOS versions also ship `curl --version` ≥ 8.x with HTTP/2 support. Linux distros use OpenSSL or GnuTLS-linked curl.

Fishunix
curl https://example.com

Same external. Fish has cleaner quoting for URLs with shell-special characters — `curl 'https://example.com/path?key=val&other=val2'` works without backslashes because fish doesn't expand `&` inside single quotes.

PowerShellwindows
Invoke-WebRequest https://example.com

PowerShell-native HTTP client (aliases `iwr`, `curl`, `wget` — but the latter two are PowerShell-specific aliases, NOT the real binaries). Returns a `[BasicHtmlWebResponseObject]` with `.Content`, `.StatusCode`, `.Headers`, `.Links`, `.Images`, `.Forms`. For JSON APIs `Invoke-RestMethod` is the sibling that auto-parses JSON into PSObjects.

cmd.exewindows
curl https://example.com

Windows 10 1803+ ships `curl.exe` natively in `C:\Windows\System32`. Identical to Unix curl. Older Windows installs have no HTTP client — use PowerShell `Invoke-WebRequest`, or call .NET via `cscript`.

Worked examples

GET a URL and write the response body to disk

Bash
curl -L https://example.com/file.zip -o file.zip
PowerShell
Invoke-WebRequest https://example.com/file.zip -OutFile file.zip
cmd.exe
curl -L https://example.com/file.zip -o file.zip

POST JSON to an API

Bash
curl -X POST -H 'Content-Type: application/json' -d '{"name":"alice"}' https://api.example.com/users
PowerShell
Invoke-RestMethod -Method POST -Uri https://api.example.com/users -Body (@{name='alice'} | ConvertTo-Json) -ContentType 'application/json'

Follow redirects and capture the response status code

Bash
curl -L -o /dev/null -s -w '%{http_code}\n' https://example.com
PowerShell
(Invoke-WebRequest https://example.com -MaximumRedirection 5).StatusCode

Gotchas

  • On Windows PowerShell 5.1, `Invoke-WebRequest` defaults to PARSING the HTML response with `mshtml.dll` (the Internet Explorer engine) — this is VERY slow on big pages and fails outright if IE is uninstalled. Always pass `-UseBasicParsing` on PS 5.1. PowerShell 7+ removed the legacy parsing path; `-UseBasicParsing` is then a no-op but still accepted.
  • `-SkipCertificateCheck` is PowerShell 7-only. On PS 5.1, to ignore TLS errors (testing only), you must hack the GLOBAL `ServicePointManager` callback: `[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }`. This sets the validator process-wide — never ship it in production scripts; isolate to a one-shot session.
  • `Invoke-WebRequest` follows redirects up to `-MaximumRedirection 5` BY DEFAULT (curl follows ONLY when given `-L`). Scripts ported from curl that assume no-follow break when the server starts returning 301/302. To match curl's default, set `-MaximumRedirection 0`.
  • `Invoke-RestMethod` AUTO-PARSES JSON responses into `[PSCustomObject]` graphs — but for non-JSON content types (XML, HTML) it returns the raw string. Some APIs return `Content-Type: application/octet-stream` even for JSON; in that case `Invoke-WebRequest` is safer (gives you the raw body to `ConvertFrom-Json` manually).
  • Both cmdlets load the ENTIRE RESPONSE BODY into memory before returning — for multi-GB downloads prefer `-OutFile` (streams to disk) or shell out to `curl.exe` with a progress meter. There is no built-in chunked-stream API in 5.1 / 7 — `-ResponseHeadersVariable` gets you headers but the body is still fully buffered.

WSL & PowerShell Core notes

pwshOn every pwsh platform `Invoke-WebRequest` and `Invoke-RestMethod` behave the same — pwsh 7+ ships the modernised non-IE parser, `-SkipCertificateCheck`, `-Authentication`, and `-AllowUnencryptedAuthentication`. The `curl` and `wget` aliases collide with the system binaries; pwsh on Linux/macOS REMOVES them so the real binaries resolve first.
WSLFrom PowerShell, `wsl curl https://...` invokes Linux curl through interop — useful when you need a specific TLS library, GNU-style flags, or a curl version newer than the Windows-bundled one. Headers and progress meters flow through cleanly. Pipes (`Invoke-WebRequest ... | wsl jq .`) cross the boundary as byte streams without re-encoding.

Common tasks using invoke-webrequest

Related commands