Public/Disable-CipherProtocol.ps1

function Disable-CipherProtocol {
    <#
    .SYNOPSIS
        Hardens the SCHANNEL configuration by disabling weak protocols and cipher suites.
    .DESCRIPTION
        Configures SCHANNEL registry keys to enable TLS 1.2 and disable TLS 1.1, TLS 1.0,
        SSL 3.0, and SSL 2.0 for both Server and Client roles. Also enforces strong crypto
        for .NET Framework applications and disables 24 known-weak TLS cipher suites.
        A system restart is required for changes to take effect.
    .INPUTS
        None. Parameters must be supplied directly.
    .OUTPUTS
        None.
    .PARAMETER ComputerName
        The target computer. Defaults to the local machine.
    .PARAMETER Force
        Restarts the computer immediately after applying changes.
    .EXAMPLE
        Disable-CipherProtocol

        Applies SCHANNEL hardening on the local machine and warns that a restart is needed.
    .EXAMPLE
        Disable-CipherProtocol -ComputerName 'Server01' -Force

        Applies SCHANNEL hardening on Server01 and restarts it immediately.
    .NOTES
        Requires Administrator privileges.
        Disabling TLS 1.0/1.1 may break legacy applications that do not support TLS 1.2.
        Test in a non-production environment before broad deployment.
        Remote operations require WinRM to be configured on the target machine.
    #>


    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')]
    [OutputType([void])]

    param (
        [Parameter(Mandatory = $false)]
        [string]$ComputerName = $env:COMPUTERNAME,

        [Parameter(Mandatory = $false)]
        [switch]$Force
    )

    $isLocal = ($ComputerName -ieq $env:COMPUTERNAME) -or
               ($ComputerName -ieq 'localhost') -or
               ($ComputerName -eq '127.0.0.1')

    if ($PSCmdlet.ShouldProcess($ComputerName, 'Enable TLS 1.2; disable TLS 1.1, TLS 1.0, SSL 3.0, SSL 2.0; disable 24 weak cipher suites')) {
        $work = {
            $schannelBase = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols'

            function Set-ProtocolState {
                param([string]$Protocol, [int]$Enabled)
                $disabled = if ($Enabled -eq 1) { 0 } else { 1 }
                foreach ($role in 'Server', 'Client') {
                    $path = "$schannelBase\$Protocol\$role"
                    New-Item -Path $path -Force | Out-Null
                    Set-ItemProperty -Path $path -Name 'Enabled'          -Value $Enabled  -Type DWord
                    Set-ItemProperty -Path $path -Name 'DisabledByDefault' -Value $disabled -Type DWord
                }
            }

            Set-ProtocolState -Protocol 'TLS 1.2' -Enabled 1
            Write-Verbose 'TLS 1.2: enabled.'

            Set-ProtocolState -Protocol 'TLS 1.1' -Enabled 0
            Write-Verbose 'TLS 1.1: disabled.'

            Set-ProtocolState -Protocol 'TLS 1.0' -Enabled 0
            Write-Verbose 'TLS 1.0: disabled.'

            Set-ProtocolState -Protocol 'SSL 3.0' -Enabled 0
            Write-Verbose 'SSL 3.0: disabled.'

            Set-ProtocolState -Protocol 'SSL 2.0' -Enabled 0
            Write-Verbose 'SSL 2.0: disabled.'

            # Enforce strong crypto for .NET Framework applications
            $dotNetPaths = @(
                (Get-ChildItem 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.*' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty PSPath),
                (Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.*'             -ErrorAction SilentlyContinue | Select-Object -ExpandProperty PSPath)
            ) | ForEach-Object { $_ }

            foreach ($path in $dotNetPaths) {
                Set-ItemProperty -Path $path -Name 'SystemDefaultTlsVersions' -Value 1 -Type DWord -ErrorAction SilentlyContinue
                Set-ItemProperty -Path $path -Name 'SchUseStrongCrypto'       -Value 1 -Type DWord -ErrorAction SilentlyContinue
            }
            Write-Verbose '.NET Framework strong crypto enforced.'

            $weakCiphers = @(
                'TLS_DHE_RSA_WITH_AES_256_CBC_SHA',
                'TLS_DHE_RSA_WITH_AES_128_CBC_SHA',
                'TLS_RSA_WITH_AES_256_GCM_SHA384',
                'TLS_RSA_WITH_AES_128_GCM_SHA256',
                'TLS_RSA_WITH_AES_256_CBC_SHA256',
                'TLS_RSA_WITH_AES_128_CBC_SHA256',
                'TLS_RSA_WITH_AES_256_CBC_SHA',
                'TLS_RSA_WITH_AES_128_CBC_SHA',
                'TLS_RSA_WITH_3DES_EDE_CBC_SHA',
                'TLS_DHE_DSS_WITH_AES_256_CBC_SHA256',
                'TLS_DHE_DSS_WITH_AES_128_CBC_SHA256',
                'TLS_DHE_DSS_WITH_AES_256_CBC_SHA',
                'TLS_DHE_DSS_WITH_AES_128_CBC_SHA',
                'TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA',
                'TLS_RSA_WITH_RC4_128_SHA',
                'TLS_RSA_WITH_RC4_128_MD5',
                'TLS_RSA_WITH_NULL_SHA256',
                'TLS_RSA_WITH_NULL_SHA',
                'TLS_PSK_WITH_AES_256_GCM_SHA384',
                'TLS_PSK_WITH_AES_128_GCM_SHA256',
                'TLS_PSK_WITH_AES_256_CBC_SHA384',
                'TLS_PSK_WITH_AES_128_CBC_SHA256',
                'TLS_PSK_WITH_NULL_SHA384',
                'TLS_PSK_WITH_NULL_SHA256'
            )

            foreach ($cipher in $weakCiphers) {
                try {
                    Disable-TlsCipherSuite -Name $cipher -ErrorAction Stop
                    Write-Verbose "Disabled cipher suite: $cipher"
                } catch {
                    if ($_.Exception.HResult -eq -1073741275) {
                        Write-Verbose "Already disabled: $cipher"
                    } else {
                        Write-Warning "Failed to disable cipher suite '$cipher': $($_.Exception.Message)"
                    }
                }
            }
        }

        if ($isLocal) {
            & $work
        } else {
            Invoke-Command -ComputerName $ComputerName -ScriptBlock $work
        }

        Write-Verbose "SCHANNEL hardening applied on '$ComputerName'."
        Write-Warning "A system restart is required for changes to take effect."

        if ($Force -and $PSCmdlet.ShouldProcess($ComputerName, 'Restart computer to apply changes')) {
            Restart-Computer -ComputerName $ComputerName -Force
        }
    }
}