5 min read
Using .NET Libraries in PowerShell - Best Practice and Quick Start
Most PowerShell cmdlets are simply wrappers around underlying .NET libraries. In this series, we’ll take a closer look...
Unlocking the Power of PowerShell: Tips for Success
In part 2 we looked at Invoke-WebRequest. Today we focus on Invoke-RestMethod: this cmdlet performs the same tasks but focuses on the data: it recognizes the format and automatically returns appropriate objects.
For example, let’s assume you want to find out where an obscure IP address is registered that you found in your logs. When you enter the URL below into your browser, you get back the registration information in a human-readable format:
The same web server can also act as a “web service”; it simply changes the data type from HTML to a machine-readable format. Try this in your browser:
https://ipinfo.io/8.8.8.8/json
This time, you receive the information in JSON format:
{
"ip": "8.8.8.8",
"hostname": "dns.google",
"city": "Mountain View",
"region": "California",
"country": "US",
"loc": "37.4056,-122.0775",
"org": "AS15169 Google LLC",
"postal": "94043",
"timezone": "America/Los_Angeles",
"readme": "https://ipinfo.io/missingauth",
"anycast": true
}
Invoke-WebRequest can retrieve any web data for you, so it can work with web services as well. However, you always receive the raw data:
$ip = '8.8.8.8'
$url = "https://ipinfo.io/$ip/json"
$result = Invoke-WebRequest -UseBasicParsing -Uri $url
The result looks exactly like in the browser before:
$ip = '8.8.8.8'
$url = "https://ipinfo.io/$ip/json"
$result = Invoke-RestMethod -UseBasicParsing -Uri $url
You would need to determine the content type yourself and then apply the appropriate conversion:
PS C:\> $result.Headers['Content-Type']
application/json; charset=utf-8
PS C:\> $formatted = $result.Content | ConvertFrom-Json
PS C:\> $formatted
ip : 8.8.8.8
hostname : dns.google
city : Mountain View
region : California
country : US
loc : 37.4056,-122.0775
org : AS15169 Google LLC
postal : 94043
timezone : America/Los_Angeles
readme : https://ipinfo.io/missingauth
anycast : True
PS C:\> $formatted.hostname
dns.google
PS C:\> $formatted.org
AS15169 Google LLC
PS C:\> $formatted | Select-Object -Property HostName, Org, Country
hostname org country
-------- --- -------
dns.google AS15169 Google LLC US
Invoke-RestMethod detects the content type and then applies the appropriate conversion automatically. If you are after the data returned by a web service, it is the much more convenient option. You simply exchange the cmdlet name:
$ip = '8.8.8.8'
$url = "https://ipinfo.io/$ip/json"
$result = Invoke-RestMethod -UseBasicParsing -Uri $url
Now, you can directly work with the data and don’t have to worry about content types or conversions:
PS C:\> $result
ip : 8.8.8.8
hostname : dns.google
city : Mountain View
region : California
country : US
loc : 37.4056,-122.0775
org : AS15169 Google LLC
postal : 94043
timezone : America/Los_Angeles
readme : https://ipinfo.io/missingauth
anycast : True
PS C:\> $result.hostname
dns.google
PS C:\> $result | Select-Object -Property HostName, Org, Country
hostname org country
-------- --- -------
dns.google AS15169 Google LLC US
The insight you just gained can be very helpful because the magic does not always work. For example, an administrator responsible for Lenovo servers wanted to make her life easier by automatically downloading the BIOS updates for her servers from Lenovo. They are publicly available right here:
https://download.lenovo.com/cdrt/td/catalogv2.xml
When you enter this URL into your browser, you see a huge XML data set. This is no different from the previous example: it is a machine-readable web service.
The admin selected Invoke-RestMethod to retrieve the information:
$Uri = 'https://download.lenovo.com/cdrt/td/catalogv2.xml'
$data = Invoke-RestMethod -Uri $Uri -UseBasicParsing
While this worked, unfortunately, the magic auto-conversion did not occur: the result was the same huge XML data set. Why?
Invoke-RestMethod tried to auto-convert the data but failed, and so would you. The conversion to XML would yield nothing.
PS C:\> $data -as [xml]
Invoke-RestMethod is only as good and capable as the data you receive. Upon closer examination, it turns out that Lenovo returns text with a few garbled bytes at the beginning:
PS C:\> $data.Substring(0,40)

Issues like this may occasionally occur and are caused by different types of text encoding. While Invoke-RestMethod cannot fix this, you can: once you remove the first five bytes, the XML conversion works as expected:
PS C:\> $xml = $data.Substring(5) -as [xml]
PS C:\> $xml.ModelList.Model
name Types BIOS SCCM
---- ----- ---- ----
ThinkCentre M715Q Types BIOS SCCM
ThinkCentre M715Q 2nd Gen Types BIOS {SCCM, SCCM, SCCM}
ThinkCentre M810Z Types BIOS {SCCM, SCCM}
ThinkCentre M625Q Types BIOS {SCCM, SCCM, SCCM}
ThinkCentre M630E Types BIOS {SCCM, SCCM}
ThinkCentre M710Q Types BIOS {SCCM, SCCM, SCCM}
...
In the end, the admin was able to automate the task with a remarkably short PowerShell script, selecting a Lenovo server, retrieving the download URL for the latest BIOS version, and downloading the binaries:
# web service url
$Uri = 'https://download.lenovo.com/cdrt/td/catalogv2.xml'
# get data and convert into correct format
$data = Invoke-RestMethod -Uri $Uri -UseBasicParsing
# fix the text encoding issue
[xml]$realData = $data.Substring(5)
# let the user select the server model
$selection = $realData.ModelList.Model |
# we care only about these two properties
Select-Object -Property Name, BIOS |
# retrieve the download URL from the nested property "#text" and move it up
ForEach-Object {
$_.BIOS = $_.BIOS.'#text'
$_
} |
Sort-Object -Property Name |
# let the user select one server type
Out-GridView -Title 'Select Server Type' -OutputMode Single
# this is what we got back
$url = $selection.BIOS
$modelname = $selection.Model -replace '\s','_'
# construct the local file name
$filename = Split-Path -Path $url -Leaf
$timestamp = Get-Date -Format 'yyyy-MM-dd'
$destinationPath = Join-Path -Path $env:temp -ChildPath "$timestamp-$modelname-$filename"
# use Invoke-WebRequest to perform the actual download
Invoke-WebRequest -UseBasicParsing -Uri $url -OutFile $destinationPath
# show the selected downloaded file in File Explorer
explorer /select,$destinationPath
Unleash the full potential of PowerShell with our handy poster. Whether you're a beginner or a seasoned pro, this cheat sheet is designed to be your go-to resource for the most important and commonly used cmdlets.
The poster is available for download and in paper form.
Mar 11, 2025 by Aleksandar Nikolić and Dr. Tobias Weltner
Most PowerShell cmdlets are simply wrappers around underlying .NET libraries. In this series, we’ll take a closer look...
Feb 25, 2025 by Aleksandar Nikolić and Dr. Tobias Weltner
In the previous parts we looked at the basic tasks Invoke-WebRequest and Invoke-RestMethod perform, and how both...
Feb 21, 2025 by Aleksandar Nikolić and Dr. Tobias Weltner
In part 2 we looked at Invoke-WebRequest. Today we focus on Invoke-RestMethod: this cmdlet performs the same tasks but...
Tobias Weltner and Aleksandar Nikolić joinly wrote the blog post series 'Tobias&Aleksandar's PowerShell tips'. So we introduce both of them here:
----------------------------
Aleksandar Nikolić is a Microsoft Azure MVP and co-founder of PowerShellMagazine.com, the ultimate online source for PowerShell enthusiasts. With over 18 years of experience in system administration, he is a respected trainer and speaker who travels the globe to share his knowledge and skills on Azure, Entra, and PowerShell. He has spoken at IT events such as Microsoft Ignite, ESPC, NIC, CloudBrew, NTK, and PowerShell Conference Europe.
----------------------------
Tobias is a long-time Microsoft MVP and has been involved with the development of PowerShell since its early days. He invented the PowerShell IDE "ISESteroids", has written numerous books on PowerShell for Microsoft Press and O'Reilly, founded the PowerShell Conference EU (psconf.eu), and is currently contributing to the advancement of PowerShell as member in the "Microsoft Cmdlet Working Group". Tobias shares his expertise as a consultant in projects and as a trainer in in-house trainings for numerous companies and agencies across Europe.