Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Using REST APIs via PowerShell

Using REST APIs via PowerShell

Slide deck that accompanied live demos I gave in a session at the Bradford Cloud User Group on 21st July 2022 showing how to use REST APIs with Azure from PowerShell.

Guy Leech

July 20, 2022
Tweet

More Decks by Guy Leech

Other Decks in Technology

Transcript

  1. Who is this Guy Leech person anyway? • 25+ years

    of hands-on working with Citrix & other EUC products • C/C++ Unix developer prior to that • Started writing code in 1980 (BASIC on a Commodore PET, age 13) • Vendor awards from Microsoft, Citrix, VMware and Parallels for community work • Day job is predominantly writing PowerShell for software vendors • Experienced Dad Joke practitioner
  2. Why use REST ? • No pre-requisites other than a

    language/tools that can drive REST, eg PowerShell • Code is more portable • REST is REST * • Learn once, use for multiple vendors/clouds/products • My personal experience/perception is that it is faster than PowerShell Az cmdlets • Why not 😊 * mostly/kinda/sorta
  3. Azure REST API • Automate deployment, changes, monitoring/alerting, etc •

    If you can do it in the Azure portal, you can do it via REST (and more) • REST API usage workflow • Authenticate • App Registration (one time although will have an expiry date) • Different app registrations for different activities for isolation ? • Generate bearer token (OAuth 2.0) • Pass bearer token in subsequent REST headers • Do stuff • Get/Set/New/Remove/etc • Add required/latest api_version for the provider to the URL • Cater for token expiry (default 1 hour) – tells you in the auth response • Cater for multiple results “pages”
  4. Credentials • Enter manually when prompted in browser window –

    not good for lights-out automation at 03:15 • Which you cannot do with REST anyway – an advantage of the Az.* PowerShell modules • Service Principal • Create an App Registration • Make a note of the Application (client) id (a GUID) • Create a Client Secret in that app registration & record the secret (password) securely (but not the Secret ID) • Add to the Access control (IAM) of the required objects, e.g. resource group, with the minimum role • e.g. “Reader” only if no requirement to create/change anything inn that object • Q. What happens when the person who set up your automation leaves?
  5. Result Paging • Typically occurs when there are >100 items

    to return (documentation says 1000) • There will be a “nextLink” property present in the response • Call the nextLink URL with the same headers/body • Optionally check not the same as previous nextLink (defensive programming) • All results returned when “nextLink” property not present • Remember not to use += for simple arrays as makes a whole new copy of existing array • Use System.Collections.Generic.List[object] and its Add() method • Or output results to pipeline and assign to an array variable or return from function • [array]$allItems = @( do … while )
  6. Tracking Asynchronous Operations • Operation returns status 201 (Created) or

    202 (Accepted) • Invoke-RestMethod does not return any JSON so use Invoke-WebRequest with same parameters • Unless using pwsh 7.x which has –ResponseHeadersVariable • Get “Azure-AsyncOperation” property from result headers • Call GET on this URL, sleeping between calls (see “Retry-After” in result headers but have a sensible default) • Loop until “status” property not equal to “InProgress” (could implement a timeout) • Take action depending on “status”
  7. Guy’s Top Tips • Where RTFMing lets you down, use

    Az.* PS modules & run with –Debug 5>debug.txt to get URLs, headers, body • Cater for transient failures (error 500, timeout & similar) – sleep & retry a small number of times • Avoid hard coding, e.g. URLs – use script parameters with defaults or declare as variable at top of script • Always think “what if this fails or what if it returns 0, 1 or more than 1 item – can my code cope?” • Watch for infinite (tight) loops • Use meaningful variable & function names, no aliases, use full named parameters & add comments/references • Plenty of examples on line but check not accidentally/intentionally malicious/destructive/stupid • Re-use/improve scripts/modules but give credit to source (e.g. in a comment) & give back to the community