The script shown in this post helps automate Windows TLS 1.0 and 1.1 security hardening. It modifies registry settings to enforce secure defaults by disabling older TLS protocols while keeping client-side security enabled.

Many organizations need to ensure that TLS 1.0 and TLS 1.1 are properly configured to prevent downgrade attacks and meet compliance requirements. This PowerShell script handles the registry modifications needed for a more secure default configuration.

If you need an automated approach to harden TLS settings on Windows endpoints, this remediation script can help you achieve consistent security posture across your infrastructure.

Prerequisites


The Script

Here is the complete remediation script that automates the TLS configuration process. The script has been cleaned and optimized for production use.

Copy and save this script as Remediation.ps1 on your systems or a deployment point.

# Initialize variables
$message = ""

# Define TLS registry paths to check and configure
$cyphers = @(
    'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client',
    'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client'
)

$items = @('Enabled', 'DisabledByDefault')

Registry Path Configuration

The script targets TLS 1.0 and 1.1 client protocols through the registry at:


Note: Server configurations are disabled in the array to focus on client-side hardening.

Variable Initialization

The script creates an array for registry paths and initializes a message log variable to track remediation actions.

# Loop through each TLS protocol path
foreach ($cypher in $cyphers) {
    # Get both Enabled and DisabledByDefault values
    foreach ($item in $items) {
        try {
            $check = Get-ItemProperty -Path $cypher -Name $item -ErrorAction Stop
            if (!($null -eq $check)) {
                $message += "$cypher $item found, Value: $($check.$item)`n"
            }
            
            # Remediate Enabled setting
            if ($item -eq "Enabled" -and $check.$item -ne 0) {
                $message += "$item incorrect, Remediation needed!`n"
                Set-ItemProperty -Path $cypher -Name $item -Value 0 -Force -Verbose
                $message += "Value set to 0`n"
            }
            
            # Remediate DisabledByDefault setting
            if ($item -eq "DisabledByDefault") {
                $message += "$item incorrect, Remediation needed!`n"
                Set-ItemProperty -Path $cypher -Name $item -Value 1 -Force -Verbose
                $message += "Value set to 1`n"
            }
        }
        catch {
            $message += "$_`n"
            $message += "`tCreating $cypher`n"
            New-Item -Path $cypher -Force
        }
    }
    
    # Create "Enabled" if it does not exist
    if (-not (Test-Path "$cypher\Enabled")) {
        $message += "`tCreating Enabled and setting value to 0`n"
        New-ItemProperty -Path $cypher -PropertyType "DWORD" -Name "Enabled" -Value 0 -Verbose -Force
    }
    
    # Create "DisabledByDefault" if it does not exist
    $message += "`tCreating DisabledByDefault and setting value to 1`n"
    New-ItemProperty -Path $cypher -PropertyType "DWORD" -Name 'DisabledByDefault' -Value 1 -Verbose -Force
}

Loop Logic Explanation

Each TLS protocol path is processed through two nested loops:


Each setting is checked and modified as needed.

How It Works

Registry Key Creation

If the registry keys for TLS 1.0 or 1.1 Client do not exist, the script creates them with a -Force parameter to prevent errors.

Registry creation is important because:


Setting Modification Logic

The script modifies two critical registry values:


OCSP Stapling for SNI

The script also handles the OCSP Stapling setting at:

HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL
    EnableOcspStaplingForSni = 0

This setting is disabled by default to improve certificate validation performance.

Key Code Snippets

Get-ItemProperty Check

This snippet safely retrieves registry values and handles missing keys gracefully:

try {
    $check = Get-ItemProperty -Path $cypher -Name $item -ErrorAction Stop
    if (!($null -eq $check)) {
        $message += "$cypher $item found, Value: $($check.$item)`n"
    }
}
catch {
    $message += "$_`n"
    $message += "`tCreating $cypher`n"
    New-Item -Path $cypher -Force
}

Set-ItemProperty Force Mode

Settings are updated with -Force to ensure changes are applied even if the value already exists:

Set-ItemProperty -Path $cypher -Name $item -Value 0 -Force -Verbose
Set-ItemProperty -Path $cypher -Name $item -Value 1 -Force -Verbose

New-ItemProperty Creation

When registry keys do not exist, New-ItemProperty creates them with proper DWORD types:

New-ItemProperty -Path $cypher -PropertyType "DWORD" -Name "Enabled" -Value 0 -Verbose -Force
New-ItemProperty -Path $cypher -PropertyType "DWORD" -Name 'DisabledByDefault' -Value 1 -Verbose -Force

Usage Examples

Running on a Single Machine

# Save the script as Remediation.ps1
.\Remediation.ps1 -Verbose

Running from an Elevated Session

# Execute with administrator rights
Start-Process powershell -ArgumentList "-NoProfile -File .\Remediation.ps1" -Verb RunAs

Script Output

The script provides verbose logging:


Verification Commands

After running the script, you can verify the changes:

# Check TLS 1.0 settings
Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client" | Select-Object Enabled, DisabledByDefault

# Check TLS 1.1 settings
Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client" | Select-Object Enabled, DisabledByDefault

Deployment Options

This script can be deployed through various enterprise mechanisms:


Conclusion

Remediation of TLS 1.0 and 1.1 settings on Windows is a critical security operation. This script provides an automated approach to enforce secure defaults and improve TLS configuration consistency across your enterprise.

By using this remediation script, you can:


Remember to test the script in a controlled environment before bulk deployment, and always maintain backup registry configurations for disaster recovery purposes.

Note: This script is for educational and remediation purposes. Always follow your organization's security policies before deploying registry modification scripts.

For more resources and the full version of this script, visit the repository linked below.

GitHub Repository

<|endoftext|><|im_start|>user