From 8e9ce75266761b5c4403dcf7e96da08f1144f15b Mon Sep 17 00:00:00 2001 From: Jordan Borean Date: Wed, 25 Feb 2026 09:11:33 +1000 Subject: [PATCH] Fix up TLS settings for pwsh bootstrapping (#86594) On some Windows hosts the TLS policies don't allow TLS 1.2 or newer by default. We add some code to the bootstrapping code to enable PowerShell to use the OS policies rather than the outdated .NET ones. This has only appeared on Azure 2016 based hosts, AWS on 2016 seems to configure the server to use the OS policies some other way. 2019+ by default aren't affected. --- .../_util/target/setup/bootstrap.ps1 | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/test/lib/ansible_test/_util/target/setup/bootstrap.ps1 b/test/lib/ansible_test/_util/target/setup/bootstrap.ps1 index 96050d72b5f..e88e0debc12 100644 --- a/test/lib/ansible_test/_util/target/setup/bootstrap.ps1 +++ b/test/lib/ansible_test/_util/target/setup/bootstrap.ps1 @@ -1,4 +1,6 @@ using namespace System.IO +using namespace System.Net +using namespace System.Reflection using namespace System.Text [CmdletBinding()] @@ -26,6 +28,39 @@ if (Test-Path -LiteralPath $pwshExe) { $zipFilename = "PowerShell-$PowerShellVersion.zip" $zipPath = [Path]::Combine([Path]::GetTempPath(), $zipFilename) +$currentProtocol = [ServicePointManager]::SecurityProtocol +if ([SecurityProtocolType].GetMember("Tls13")) { + # If the Tls13 member is present we are on .NET Framework 4.8+ so using + # the SystemDefault setting will use the OS policies. If it's not set + # to SystemDefault already we are running in a PSRemoting WSMan host + # and need some reflection to reconfigure the policies to get it to use + # the OS policies. + + if ($currentProtocol -ne 'SystemDefault') { + # https://learn.microsoft.com/en-us/dotnet/framework/network-programming/tls#switchsystemnetdontenablesystemdefaulttlsversions + $disableSystemTlsField = [ServicePointManager].GetField( + 's_disableSystemDefaultTlsVersions', + [BindingFlags]'NonPublic, Static') + if ($disableSystemTlsField -and $disableSystemTlsField.GetValue($null)) { + $disableSystemTlsField.SetValue($null, $false) + } + + [ServicePointManager]::SecurityProtocol = [SecurityProtocolType]::SystemDefault + } +} +else { + # We are on .NET 4.7 or older, as TLS 1.2 is the max version we can + # use here regardless of the OS, manually enable the protocols known to + # the runtime. + if ([SecurityProtocolType].GetMember("Tls11")) { + $currentProtocol = $currentProtocol -bor [SecurityProtocolType]::Tls11 + } + if ([SecurityProtocolType].GetMember("Tls12")) { + $currentProtocol = $currentProtocol -bor [SecurityProtocolType]::Tls12 + } + [ServicePointManager]::SecurityProtocol = $currentProtocol +} + if (-not (Test-Path -LiteralPath $zipPath)) { $attempts = 0