changing to Survey based on Joonas’ comment below – request is to have a flag to force TLS 1.2.Joonas Tuomisto commented
As Sami's colleague I can elaborate.
It seems like the underlying .NET library advertises TLS 1.0 only in its ClientHello (by default) for some unknown reason - a TLS client should advertise the most recent supported version by default.
So, when you attempt to connect to a web service that has only TLS 1.2 enabled, all you get is a cryptic, though technically accurate .NET error:
"Invoke-WebRequest : The underlying connection was closed: An unexpected error occurred on a send."
After scratching my head for a bit, I grabbed Wireshark to see what was happening on the wire:
1) TCP handshake
2) PowerShell / .NET sends a TLS ClientHello with a version flag of TLS 1.0
3) As the server only supports TLS 1.2, it will terminate the connection with TCP RST
The client will repeat this same procedure once more and then spout out the error message.
To make it work, you need to either enable TLS 1.0 (undesirable), or do this once per PowerShell session:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::TLS12
After which the client will successfully handshake with TLS 1.2.
Therefore, it would be nice to have a switch for Invoke-WebRequest / Invoke-RestMethod that allows you to specify the TLS version, but obviously it would be even nicer to do TLS handshakes properly and attempt them with the highest supported version by default.
If this is operating system / .NET version / PowerShell version dependent, I'm using:
- Windows 7 fully patched
- .NET Framework 4.6.1
- WMF 4.0 i.e. PowerShell 4