PowerShell: Enable TLS 1.2 on legacy servers

# Enable TLS 1.2 on legacy servers
function enableTls12{
$windowsVersionNumber=[System.Environment]::OSVersion.Version.Major;
#$windowsName=(Get-CimInstance -ClassName Win32_OperatingSystem).Caption; #The term 'Get-CimInstance' is not recognized as the name of a cmdlet, function, script file, or operable program.
$windowsName=(Get-WmiObject Win32_OperatingSystem).Caption; #Backward compatible to legacy Windoze
$dotNetSecurityProtocols=[enum]::GetNames([Net.SecurityProtocolType]);
write-host "These are the default protocols on this $windowsName machine:`r`n$dotNetSecurityProtocols";

if ($windowsVersionNumber -lt 10){
$tls12Available=[System.Net.ServicePointManager]::SecurityProtocol -match "(Tls12|3072)";
if(!($tls12Available)){
write-host "This legacy Windows version does not have TLS 1.2 capability. Now adding that feature...";
$hive="REGISTRY::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols"
$key="TLS 1.2"
$key1="Client"; $key1Dword1="DisabledByDefault"; $key1Dword1Value=0; $key1Dword2="Enabled"; $key1Dword2Value=1;
$key2="Server"; $key2Dword1="DisabledByDefault"; $key2Dword1Value=0; $key2Dword2="Enabled"; $key2Dword2Value=1;
if(!(Test-Path "$hive\$key")){New-Item -Path "$hive\$key" -Force | Out-Null}
if(!(Test-Path "$hive\$key\$key1")){New-Item -Path "$hive\$key\$key1" -Force | Out-Null}
if(!(Test-Path "$hive\$key\$key2")){New-Item -Path "$hive\$key\$key2" -Force | Out-Null}

New-ItemProperty -Path "$hive\$key\$key1" -Name $key1Dword1 -Value $key1Dword1Value -PropertyType DWORD -Force | Out-Null
New-ItemProperty -Path "$hive\$key\$key1" -Name $key1Dword2 -Value $key1Dword2Value -PropertyType DWORD -Force | Out-Null

New-ItemProperty -Path "$hive\$key\$key2" -Name $key2Dword1 -Value $key2Dword1Value -PropertyType DWORD -Force | Out-Null
New-ItemProperty -Path "$hive\$key\$key2" -Name $key2Dword2 -Value $key2Dword2Value -PropertyType DWORD -Force | Out-Null

# PowerShell 2.0: explicit casting of TLS12 and apply it to session
$castTLS12 = [Enum]::ToObject([System.Net.SecurityProtocolType], 3072);
[System.Net.ServicePointManager]::SecurityProtocol = $castTLS12;
#[System.Net.ServicePointManager]::SecurityProtocol += $castTLS12;
}else{
write-host "This legacy Windows version already has TLS 1.2 capability added.";
}
}else{ #Windows 10 / 2016 Server and above
$tls12Available=[Enum]::GetNames([Net.SecurityProtocolType]) -contains 'Tls12';
if(!($tls12Available)){
write-host "Setting TLS 1.1 & 1.2 as the default security protocols.";
$hiveInternet32bit="REGISTRY::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings"
#$hiveInternet64bit="REGISTRY::HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Internet Settings"
$hiveInternetKey="WinHttp"
$hiveInternetDword="DefaultSecureProtocols"
$hiveInternetDwordValue="0x00000A00" #Tls 1.1 & 1.2
New-ItemProperty -Path "$hiveInternet32bit\$hiveInternetKey" -Name $hiveInternetDword -Value $hiveInternetDwordValue -PropertyType DWORD -Force | Out-Null
#New-ItemProperty -Path "$hiveInternet64bit\$hiveInternetKey" -Name $hiveInternetDword -Value $hiveInternetDwordValue -PropertyType DWORD -Force | Out-Null
}
# Enable TLS1.2 as Default
$tls12InUse=[System.Net.ServicePointManager]::SecurityProtocol.HasFlag([Net.SecurityProtocolType]::Tls12);
if (!($tls12InUse)){
write-host "Setting TLS 1.2 as the default security protocol for the dotNet Framework...";
$hive32bit="REGISTRY::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319";$key32bit="SchUseStrongCrypto";$key32bitValue=1
$hive64bit="REGISTRY::HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319";$key64bit="SchUseStrongCrypto";$key64bitValue=1
New-ItemProperty -Path $hive32bit -Name $key32bit -Value $key32bitValue -PropertyType DWORD -Force | Out-Null
New-ItemProperty -Path $hive64bit -Name $key64bit -Value $key64bitValue -PropertyType DWORD -Force | Out-Null
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
}
}

# Set default protocol to TLS 1.2 and bypass certificate trust issues
$classTrustAllCerts = @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate,WebRequest request, int certificateProblem) {
return true;
}
}
"@
try{
Add-Type -TypeDefinition $classTrustAllCerts
$trustAllCertsPolicy=New-Object TrustAllCertsPolicy
[System.Net.ServicePointManager]::CertificatePolicy = $trustAllCertsPolicy
}catch{}
try{
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12;
}catch{
[System.Net.ServicePointManager]::SecurityProtocol = [Enum]::ToObject([System.Net.SecurityProtocolType], 3072);
}
}
enableTls12
<# What problems does this solve?
# 1. Unable to make HTTPS call within PowerShell 2.0
PS C:\Users\yomama> Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
Exception calling "DownloadString" with "1" argument(s): "The underlying connection was closed: An unexpected error occurred on a send."
At line:1 char:104
+ Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString <<<< ('https://chocolatey.org/install.ps1'))
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException

# 2. Error when trying to load the correct SSL version into PowerShell
# - [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# - [Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
Exception setting "SecurityProtocol": "Cannot convert null to type "System.Net.SecurityProtocolType" due to invalid enumeration values. Specify one of the following enumeration values and try again. The possible enumeration values are "Ssl3, Tls"."
At line:1 char:28
+ [Net.ServicePointManager]:: <<<< SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyAssignmentException
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12

add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"@
#[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
#[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Ssl3, [Net.SecurityProtocolType]::Tls, [Net.SecurityProtocolType]::Tls11, [Net.SecurityProtocolType]::Tls12

$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

$hasInternetAccess=Get-NetRoute | ? DestinationPrefix -eq '0.0.0.0/0' | Get-NetIPInterface | Where ConnectionState -eq 'Connected'
$hasInternetAccess=test-connection 8.8.8.8 -Count 1 -Quiet
$hasInternetAccess=test-netconnection google.com -port 443 -InformationLevel Quiet
#>

Leave a Reply

Your email address will not be published. Required fields are marked *