Forcing SSL and TLS Protocols With PowerShell Invoke-WebRequest

In working on script to grab some data from a suppliers API I encountered some errors when running Invoke-WebRequest

Invoke-WebRequest : The underlying connection was closed: An unexpected error occurred on a send.
At line:1 char:1
+ Invoke-WebRequest -Method Get -Uri $APIURL -Headers @{"Authorization" ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

We can get further details with $Error[0].Exception.InnerException

Authentication failed because the remote party has closed the transport stream.

Having seen this before, I suspected the issue was due to mismatched TLS/SSL support. First step is to determine what protocols our suppliers API supports. The quickest way I’ve found to do this is using the SSL Server Test provided by SSL Labs. When we scroll down to the Configuration section, under Protocols we can see what the API service supports.

Supported SSL/TLS Protocols

With only TLS 1.2 being supported, we can now force PowerShell to use the same on the client side.

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

And with that, if we retry our request…

Invoke-WebRequest : {"statusCode":200, ...}