PowerShell REST API and Web Requests
REST APIs are the standard way modern applications communicate over the internet. Almost every cloud platform, SaaS tool, payment gateway, monitoring service, and business application exposes a REST API. PowerShell's Invoke-RestMethod and Invoke-WebRequest cmdlets let scripts consume APIs, post data, retrieve reports, trigger workflows, and integrate systems — all without a browser or third-party tools.
How REST APIs Work
PowerShell Script REST API Server +-----------------+ +------------------+ | Invoke-RestMethod|--HTTP---> | GET /api/users | | | | POST /api/orders | | | | PUT /api/item/5 | | | | DELETE /api/job/3| | |<--JSON--- | Returns Data | +-----------------+ +------------------+
HTTP Methods
| Method | Purpose | Example Action |
|---|---|---|
| GET | Retrieve data | Get a list of users |
| POST | Create new data | Create a new order |
| PUT | Replace/update data | Update a user's full record |
| PATCH | Partial update | Change only the email field |
| DELETE | Remove data | Delete a record |
Invoke-RestMethod – The Primary API Cmdlet
Invoke-RestMethod sends HTTP requests and automatically parses JSON or XML responses into PowerShell objects — no manual parsing needed.
GET Request – Retrieve Data
# Fetch public user data (JSONPlaceholder – a free test API)
$response = Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/users/1" -Method GET
Write-Host "Name: $($response.name)"
Write-Host "Email: $($response.email)"
Write-Host "Company: $($response.company.name)"
Write-Host "City: $($response.address.city)"
Output:
Name: Leanne Graham
Email: Sincere@april.biz
Company: Romaguera-Crona
City: Gwenborough
GET a List of Items
# Get all posts from the test API
$posts = Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/posts" -Method GET
Write-Host "Total posts: $($posts.Count)"
# Show first 3 posts
$posts | Select-Object -First 3 | ForEach-Object {
Write-Host "Post $($_.id): $($_.title)"
}
POST Request – Send Data
# Define the data to send
$newPost = @{
title = "PowerShell REST API Guide"
body = "This tutorial covers REST API usage with PowerShell."
userId = 1
}
# Convert to JSON and POST
$response = Invoke-RestMethod `
-Uri "https://jsonplaceholder.typicode.com/posts" `
-Method POST `
-Body ($newPost | ConvertTo-Json) `
-ContentType "application/json"
Write-Host "Created Post ID: $($response.id)"
Write-Host "Title: $($response.title)"
Output:
Created Post ID: 101
Title: PowerShell REST API Guide
PUT and PATCH Requests – Update Data
# PUT – replace the full record
$updatedPost = @{
id = 1
title = "Updated Title"
body = "Updated body content."
userId = 1
}
$response = Invoke-RestMethod `
-Uri "https://jsonplaceholder.typicode.com/posts/1" `
-Method PUT `
-Body ($updatedPost | ConvertTo-Json) `
-ContentType "application/json"
Write-Host "Updated: $($response.title)"
# PATCH – update only specific fields
$patch = @{ title = "Only Title Changed" }
$response = Invoke-RestMethod `
-Uri "https://jsonplaceholder.typicode.com/posts/1" `
-Method PATCH `
-Body ($patch | ConvertTo-Json) `
-ContentType "application/json"
Write-Host "Patched: $($response.title)"
DELETE Request
$response = Invoke-RestMethod `
-Uri "https://jsonplaceholder.typicode.com/posts/1" `
-Method DELETE
Write-Host "Deleted. Response: $($response | ConvertTo-Json)"
Authentication Methods
API Key in Header
$apiKey = "your-api-key-here"
$headers = @{
"Authorization" = "Bearer $apiKey"
"Content-Type" = "application/json"
"Accept" = "application/json"
}
$response = Invoke-RestMethod `
-Uri "https://api.example.com/v1/data" `
-Method GET `
-Headers $headers
$response | Format-Table
Basic Authentication
$username = "admin"
$password = "Password123"
$base64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("$username`:$password"))
$headers = @{
"Authorization" = "Basic $base64"
}
$response = Invoke-RestMethod `
-Uri "https://api.example.com/users" `
-Method GET `
-Headers $headers
OAuth2 Token
# Step 1 – Get the token
$tokenBody = @{
grant_type = "client_credentials"
client_id = "your-client-id"
client_secret = "your-client-secret"
scope = "api.read"
}
$tokenResponse = Invoke-RestMethod `
-Uri "https://auth.example.com/oauth/token" `
-Method POST `
-Body $tokenBody
$token = $tokenResponse.access_token
Write-Host "Token obtained."
# Step 2 – Use the token
$headers = @{ "Authorization" = "Bearer $token" }
$data = Invoke-RestMethod `
-Uri "https://api.example.com/v1/reports" `
-Method GET `
-Headers $headers
$data | Format-Table
Invoke-WebRequest – Lower-Level HTTP Access
Invoke-WebRequest returns the raw HTTP response including headers, status code, and content. Use it when full HTTP response details are needed.
$response = Invoke-WebRequest -Uri "https://jsonplaceholder.typicode.com/posts/1"
# HTTP status code
Write-Host "Status Code: $($response.StatusCode)"
# Response headers
$response.Headers["Content-Type"]
# Raw response body (string)
$response.Content
# Parse JSON content manually
$data = $response.Content | ConvertFrom-Json
Write-Host $data.title
Handling API Errors
try {
$response = Invoke-RestMethod `
-Uri "https://api.example.com/data/999" `
-Method GET `
-Headers $headers `
-ErrorAction Stop
}
catch {
$statusCode = $_.Exception.Response.StatusCode.value__
$message = $_.Exception.Message
Write-Host "HTTP Error $statusCode : $message" -ForegroundColor Red
switch ($statusCode) {
401 { Write-Host "Unauthorized – check your API key" }
403 { Write-Host "Forbidden – insufficient permissions" }
404 { Write-Host "Resource not found" }
429 { Write-Host "Rate limited – slow down requests" }
500 { Write-Host "Server error – try again later" }
Default { Write-Host "Unexpected error" }
}
}
Pagination – Retrieving Large Datasets
$allItems = @()
$page = 1
$pageSize = 100
do {
$url = "https://api.example.com/items?page=$page&limit=$pageSize"
$response = Invoke-RestMethod -Uri $url -Method GET -Headers $headers
$allItems += $response.items
Write-Host "Page $page – loaded $($response.items.Count) items"
$page++
} while ($response.hasMore -eq $true)
Write-Host "Total items loaded: $($allItems.Count)"
Real-World Example – Get GitHub Repository Info
function Get-GitHubRepoInfo {
param (
[string]$Owner,
[string]$Repo
)
$url = "https://api.github.com/repos/$Owner/$Repo"
$headers = @{
"Accept" = "application/vnd.github+json"
"User-Agent" = "PowerShell-Client"
}
try {
$repo = Invoke-RestMethod -Uri $url -Method GET -Headers $headers
[PSCustomObject]@{
Name = $repo.name
Description = $repo.description
Stars = $repo.stargazers_count
Forks = $repo.forks_count
Language = $repo.language
LastUpdated = $repo.updated_at
URL = $repo.html_url
}
}
catch {
Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Red
}
}
$info = Get-GitHubRepoInfo -Owner "PowerShell" -Repo "PowerShell"
$info | Format-List
Output:
Name : PowerShell
Description : PowerShell for every system!
Stars : 44000
Forks : 7200
Language : C#
LastUpdated : 2026-03-20T14:22:00Z
URL : https://github.com/PowerShell/PowerShell
Invoke-RestMethod Parameters Reference
| Parameter | Purpose | Example |
|---|---|---|
| -Uri | API endpoint URL | "https://api.example.com/data" |
| -Method | HTTP verb | GET, POST, PUT, PATCH, DELETE |
| -Headers | HTTP headers hash table | @{"Authorization"="Bearer token"} |
| -Body | Request body (POST/PUT) | $data | ConvertTo-Json |
| -ContentType | Data format of body | "application/json" |
| -OutFile | Save response to file | "C:\Downloads\file.pdf" |
| -TimeoutSec | Request timeout in seconds | 30 |
| -ErrorAction | Error handling behavior | Stop |
| -SkipCertificateCheck | Ignore SSL errors (PS7) | $true (dev only) |
Summary
Invoke-RestMethod is the gateway between PowerShell and the connected world of APIs. GET requests retrieve data, POST creates it, PUT and PATCH update it, and DELETE removes it. Authentication through API keys, Basic Auth, and OAuth2 tokens covers virtually every API security model. Error handling with try-catch and HTTP status codes makes API calls robust. Pagination loops collect large datasets reliably. REST API integration unlocks GitHub, Azure, Slack, ServiceNow, Salesforce, Jira, and thousands of other platforms — all from PowerShell scripts.
