Search code examples
powershellinvoke-webrequestinvoke-restmethod

powershell invoke-webrequest does not work but invoke-restmethod works


I want to get the content of a web page and when I use

$web = Invoke-RestMethod -Uri "https://inkscape.org/" I will get the content but when I use

$web = Invoke-WebRequest -Uri "https://inkscape.org/" I won't get anything why it happens?? and what is the difference exactly ??


Solution

  • Simply put, for plain-text or HTML response bodies, the relationship between the (older) Invoke-WebRequest cmdlet and the Invoke-RestMethod cmdlet is as follows with the respect to the default GET method:

    # -UseBasicParsing is only needed in *Windows PowerShell*.
    (Invoke-WebRequest -UseBasicParsing -Uri "https://inkscape.org/").Content
    

    is the same as:

    Invoke-RestMethod -Uri "https://inkscape.org/"
    

    That is:

    • Invoke-WebRequest returns a response object whose .Content property contains the body of the response, always as text (except if you save the raw body to a file with -OutFile).

      • For HTML response bodies, Windows PowerShell attempts to also parse the HTML text into an HTML DOM, surfaced via the .ParsedHTML property, using the obsolete Internet Explorer. -UseBasicParsing suppresses this. This switch has no effect in PowerShell (Core) 7+, which fundamentally doesn't support parsing HTML, requiring third-party solutions (see this answer for an example) or - on Windows only - a COM-based solution (see this answer).
    • Invoke-RestMethod directly returns the response body (only).

      • Additionally, if the target site indicates that XML or JSON data is being returned, Invoke-RestMethod doesn't return the body as text, but automatically parses it into an [xml] instance / [System.Xml.XmlElement] instances (for RSS / Atom feeds) or a [pscustomobject] graph (ConvertFrom-Json is built in, so to speak).

      • Even in the absence of a known response data format, PowerShell tries to parse the response body, first as XML, then as JSON; if all attempts fail, plain text (a [string] instance) is returned.

      • Even for text/html responses an attempt is made to parse them as XML. That is, if a page happens to be valid XML (which is rare these days), you'll get an [xml] instance back; for instance, the very simple HTML5 page at https://httpbin.org/html happens to be valid XML (excluding the <!DOCTYPE html> declaration), whereas HTML5 pages in general are not. Thus,
        (Invoke-RestMethod https://httpbin.org/html).GetType().FullName returns System.Xml.XmlDocument, i.e. an [xml] instance.