5

When executing the line Invoke-WebRequest -Uri https://www.freehaven.net/anonbib/date.html PowerShell throws WebCmdletResponseException. How can I get more information about it, and what may be causing this? While I can successfully get the contents of the page using Python, but in PowerShell it throws an exception.

Full exception:

Invoke-WebRequest : The underlying connection was closed: An unexpected error occurred on a send.
At line:1 char:1
+ Invoke-WebRequest -Uri https://www.freehaven.net/anonbib/date.html
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebExc
   eption
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

2 Answers 2

13

This is because Invoke-WebRequest uses HttpWebRequest under the hood, which in all but the most recent versions of .Net defaults to using SSLv3 and TLSv1.

You can see this by looking at the current value:

[System.Net.ServicePointManager]::SecurityProtocol

The site you're connecting to only supports TLS 1.2.

You can change the allowed protocols, but it applies globally during your application's run:

[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12

This overwrites the value.

Of course that would break anything else in your application which relies on a connection to a server that doesn't support TLS 1.2

A safe method might be to add TLS 1.2:

[System.Net.ServicePointManager]::SecurityProtocol = (
    [System.Net.ServicePointManager]::SecurityProtocol -bor 
    [System.Net.SecurityProtocolType]::Tls12
)

# parentheses are for readability

On the off-chance this still causes a problem for other sites (not sure what, maybe a site that says it accepts TLS 1.2 but its implementation is broken while its TLS 1.0 works fine?), you can save the previous value and restore it.

$cur = [System.Net.ServicePointManager]::SecurityProtocol]
try {
    [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
    Invoke-WebRequest -Uri https://www.freehaven.net/anonbib/date.html
} finally {
    [System.Net.ServicePointManager]::SecurityProtocol = $cur
}
Sign up to request clarification or add additional context in comments.

4 Comments

I got the same error (The underlying connection was closed) and used the solution that you mentioned above but unfortunately, it now throws an error like this "Invoke-RestMethod : The remote server returned an error: (503) Server Unavailable." Would you know any solution for this?
@Abhi it sounds like that is a separate issue. The connection closed means it wasn't supporting TLS 1.0. If you were still having a TLS issue, the connection would be closed before you could receive the HTTP status code 503, so it seems your TLS issues are solved. But any 500 level error is likely to be the responsibility of the site owner, not the client, so you'll have to check with them I think.
You're right! It is an issue on the server that it was unavailable.
Great answer, with exactly the cause and fix I needed!
0

If you just need to access some address, like running some sort of webhook, you can use curl, which is in Windows 10 by default.

No need to set separate hoops to get around certificate checking by overriding global callbacks.

$response = & curl.exe --insecure -X GET "$TriggerURL"
if ($response -notmatch "ok") {
 # Failed
 ...

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.