Add support for TLS 1.2 (Invoke-WebRequest, Invoke-RestMethod)
Invoke-WebRequest and Invoke-RestMethod commands only support TLS 1.0 protocol. We need to have a native support for newer TLS (1.2) versions for modern web interfaces.
changing to Survey based on Joonas’ comment below – request is to have a flag to force TLS 1.2.
Da Tao commented
Please add the support. Also, please enable TLS 1.1 - so the client supports almost all web interfaces.
Fun fact: the Powershell script for intalling release agent in TFS 2018 does not work on Windows 2012.
Michael Koehler commented
Another vote for this to be fixed. Install-PackageProvider -Name NuGet fails on a newly installed Windows 2016 server.
I'm not sure there's anything to run survey for. This looks like a bug to me. These cmdlets should negotiate the highest available protocol version first.
While having Protocol parameter would be helpful, but it looks more like an extra feature to me, rather than a bug fix. With more services disable anything older than TLS1.2 adding in [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 everywhere becomes a mandatory action
Ed Gillett commented
I just got bitten by this one on a Windows Server 2016 connecting to VSTS git endpoints over HTTPS. Had to force TLS 1.2 ([Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::TLS12)
Daniel Salzedo commented
I have also found this applies to the System.Net.WebClient object. If you call the DownloadFile method for an TLS URL on a server that supports only TLS v1.1 or 1.2 it will fail with this error:
"Exception calling "DownloadFile" with "2" argument(s): "An exception occurred during a WebClient request.
Any Powershell component that invokes a TLS connection should act like any other normal TLS client. It should negotiate the highest level of TLS available (v1.2 at present) first and then degrade down to TLS v1.1 and 1.0 only if this does not succeed. Having the ability to control this if needed via [Net.ServicePointManager]::SecurityProtocol is useful but it should not be required unless fine-grained control is needed for some reason. (BTW Thank you Joonas Tuomisto for posting that as a work-around)
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