PowerShell – The underlying connection was closed: An unexpected error occurred on a send.

What should have been just another quick script as a WebRequest to get some data turned into a debugging session when both Invoke-RestMethod and Invoke-WebRequest returned The underlying connection was closed: An unexpected error occurred on a send.

Invoke-RestMethod

Invoke-RestMethod : The underlying connection was closed: An unexpected error occurred on a send.
At line:1 char:15
+ ... postdata2 = Invoke-RestMethod -Uri $post.URL -Method Get -UserAgent $ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

Invoke-WebRequest

Invoke-WebRequest : The underlying connection was closed: An unexpected error occurred on a send.
At line:3 char:21
+ ... $postdata = Invoke-WebRequest -Uri $post.URL -Method Get -UserAgent $ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

It’s not unusual for PowerShell defaults to have issues with TLS and the ambiguous nature of the error made me jump to the conclusion I probably just needed to enforce TLS 1.2 using this one-liner.

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

But, no joy. Same error.

Looking at the certificate for the URL my script was connecting to show the certificate was valid.

Certificate is Valid.PNG

After a bunch of searching and actually getting a couple of working scenarios from (here and here) they weren’t ideal. The resolution was to allow TLS, TLS 1.1 and TLS 1.2 by using the following line before invoking the WebRequest.

Posting this as I know I’ll need it again in the future and it will allow me to find it quickly.

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12