← PowerShell course
8

Talking to REST APIs

30 min

Connect your scripts to the world around them — query a CMDB, post to a Teams webhook, and drive your infrastructure through HTTP.

By the end you can
  • Explain the difference between Invoke-RestMethod and Invoke-WebRequest
  • Perform authenticated GET requests using bearer-token headers
  • Serialise a PowerShell hashtable to JSON and POST it to an API
  • Iterate a collection returned from a REST endpoint
  • Apply try/catch error handling around HTTP calls

Talking to REST APIs

Modern infrastructure runs on HTTP. Your CMDB, monitoring platform, ticketing system, and chat tools all expose REST APIs — and PowerShell speaks HTTP fluently.

Invoke-RestMethod vs Invoke-WebRequest

CmdletReturnsBest for
Invoke-RestMethodParsed objects (JSON to objects automatically)REST APIs returning JSON/XML
Invoke-WebRequestRaw response (.Content, .StatusCode)Web scraping, binary downloads

For REST APIs, always prefer Invoke-RestMethod — it hands you a live object you can dot-navigate immediately.

$server = Invoke-RestMethod -Uri 'https://cmdb.corp.local/api/servers/SRV042'
$server.hostname   # 'SRV042'
$server.os         # 'Windows Server 2022'

GET with headers (authentication)

Most APIs require a bearer token or API key. Pass them via a hashtable to -Headers:

$headers = @{
    'Authorization' = "Bearer $token"
    'Accept'        = 'application/json'
}

$response = Invoke-RestMethod -Uri 'https://cmdb.corp.local/api/servers' -Headers $headers

Store tokens in $env: variables or a secrets vault — never hard-code them.

Building a request body and POST-ing

Construct the payload as a hashtable, serialise it with ConvertTo-Json, then POST:

$body = @{
    title   = 'Patch window tonight'
    servers = @('SRV042', 'SRV043')
    urgency = 'high'
} | ConvertTo-Json

Invoke-RestMethod -Uri 'https://cmdb.corp.local/api/changes' -Method Post -Headers $headers -Body $body -ContentType 'application/json'

-ContentType 'application/json' tells the server how to decode the body — don't omit it.

Iterating a collection response

$servers = Invoke-RestMethod -Uri 'https://cmdb.corp.local/api/servers?env=prod' -Headers $headers

foreach ($srv in $servers) {
    Write-Host "$($srv.hostname) — $($srv.os) — $($srv.status)"
}

Error handling

-WhatIf doesn't apply to HTTP calls, so use try/catch:

try {
    $result = Invoke-RestMethod -Uri 'https://cmdb.corp.local/api/servers' -Headers $headers
} catch {
    Write-Error "API call failed: $($_.Exception.Message)"
}