PowerShell provides two cmdlets for accessing websites and web services: Invoke-RestMethod and Invoke-WebRequest. Let's discover how they work.

They appear to function similarly and support identical parameters:

$url = 'https://devblogs.microsoft.com/powershell/'

$result1 = Invoke-WebRequest -Uri $url -UseBasicParsing -TimeoutSec 1
$result2 = Invoke-RestMethod -Uri $url -UseBasicParsing -TimeoutSec 1  

And thats trueat least in the initial stage: both cmdlets contact the web server and retrieve information.

  • The more basic Invoke-WebRequest returns the raw response, including all connection details
  • Invoke-RestMethod processes the response and focuses on the data. It examines the content type (e.g., text, JSON, XML) and attempts to automatically convert the data, returning ready-to-use objects.

NOTE: The -UseBasicParsing parameter and PowerShell 7

In Windows PowerShell, the -UseBasicParsing parameter forces the use of a built-in parser instead of relying on Internet Explorer's parsing capabilities. Since Internet Explorer is deprecated and absent from non-Windows operating systems, you should always use this parameter in Windows PowerShell.

In PowerShell 7, the -UseBasicParsing parameter has been deprecated. All web requests now use basic parsing by default. This parameter remains for backward compatibility but has no effect on the cmdlets operation.

Both cmdlets work well in Windows PowerShell, but numerous additions and improvements have been made in PowerShell 7.

One of these useful enhancements: if the web service or server you are accessing returns an error, it was originally always emitted and could not be suppressed or handled. Here is a test website that returns a 404 Not Found error:

Invoke-RestMethod https://example.org/NoSuchPageExists -ErrorAction Ignore 

PowerShell 7 has resolved this issuealong with many othersand introduced the -SkipHttpErrorCheck switch parameter, which suppresses exceptions at the web client level.

Invoke-RestMethod https://example.org/NoSuchPageExists  -SkipHttpErrorCheck 

Differences

With Invoke-WebRequest, you can examine the server connection and, for example, view the original response code:

PS C:\> $result1 | Select-Object -Property StatusCode, StatusDescription

StatusCode StatusDescription
---------- -----------------
       200 OK

You can also retrieve detailed information about the underlying connection, such as the location of the delivering server or whether the content was served from a cache:

PS C:\> $result1.BaseResponse

IsMutuallyAuthenticated : False
Cookies                 : {}
Headers                 : {Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers, Link...}
SupportsHeaders         : True
ContentLength           : -1
ContentEncoding         : 
ContentType             : text/html; charset=UTF-8
CharacterSet            : UTF-8
Server                  : nginx
LastModified            : 31.01.2025 08:02:16
StatusCode              : OK
StatusDescription       : OK
ProtocolVersion         : 1.1
ResponseUri             : https://devblogs.microsoft.com/powershell/
Method                  : GET
IsFromCache             : False

All HTTP headers remain visible and can be inspected, including cookies if any were sent:

PS C:\> $result1.Headers

Key                          Value                                                                                                          
---                          -----                                                                                                          
Access-Control-Allow-Origin  https://dev.quantum.microsoft.com                                                                              
Access-Control-Allow-Methods GET, POST, OPTIONS                                                                                             
Access-Control-Allow-Headers Content-Type, Authorization                                                                                    
Link                         ; rel="https://api.w.org/"                                 
X-Cacheable                  bot                                                                                                            
X-Cache-Group                bot                                                                                                            
X-XSS-Protection             1; mode=block,1; mode=block                                                                                    
Transfer-Encoding            chunked                                                                                                        
Connection                   keep-alive,Transfer-Encoding                                                                                   
Feature-Policy               geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera 'none'; magnetometer 'none'; gyr...
Referrer-Policy              no-referrer-when-downgrade                                                                                     
X-Content-Type-Options       nosniff                                                                                                        
X-Frame-Options              SAMEORIGIN                                                                                                     
Content-Security-Policy      script-src 'self' 'unsafe-inline' 'unsafe-eval' https:                                                         
Strict-Transport-Security    max-age=15768000 ; includeSubDomains ; preload                                                                 
Cache-Control                must-revalidate, max-age=10800                                                                                 
Content-Type                 text/html; charset=UTF-8                                                                                       
Date                         Fri, 31 Jan 2025 08:44:57 GMT                                                                                  
Server                       nginx                                                                                                          
X-Powered-By                 WP Engine

If you need the actual data content, you receive only the raw content and must convert it into an object format yourself:

PS C:\> $result1.Content

($result1.RawContent returns the complete raw response including HTTP headers)

When Content Is Your Priority

Invoke-RestMethod, on the other hand, focuses on the content rather than the underlying connection. It immediately returns the processed content, with no need to specify additional properties.

PS C:\> $result2

In this simple example, the content was HTML, so the content type was "string," and both cmdlets returned the same content. This changes when you work with actual web services that deliver structured content types, such as JSON or XML, which we will explore in the second part of this series.

Conclusions

For now, you know that Invoke-WebRequest and Invoke-RestMethod both perform the same basic function. However, Invoke-RestMethod goes a step further by processing the data, while Invoke-WebRequest allows you to view the underlying connection details.

Your ultimate PowerShell Cheat Sheet

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.

Get your poster here!

Related links