PowerCLI – Disable TLS 1.0 1.1 SSLV3 on ESXi 6.x while in maintenance mode

PowerCLI

The PowerCLI script takes Function Set-ESXiDPC from https://github.com/lamw/vghetto-scripts/blob/master/powershell/ESXiDisableProtocolConfiguration.ps1 (via Cluster) but makes sure the single ESXi host in is maintenance mode.   The script was tested on ESXi 6.0 + 6.5 with a 6.5 VCSA that is TLS 1.2 only.

Download Win32 OpenSSL v1.1.0g Light https://slproweb.com/products/Win32OpenSSL.html

 

Test TCP port 443 over TLS 1.0 and 1.1 before and after the reboot (yes, there are other ports that can be tested)
openssl.exe s_client -connect esxi-vsan1.my.lab:443 -tls1
openssl.exe s_client -connect esxi-vsan1.my.lab:443 -tls1_1

 

<#
https://vmscribble.com PowerCLI 6.5.4
Pulled Nov 29, 2017 https://github.com/lamw/vghetto-scripts/blob/master/powershell/ESXiDisableProtocolConfiguration.ps1 The PowerCLI script takes Function Set-ESXiDPC (via Cluster) but makes sure the single ESXi host in is maintenance mode.
The script was tested on ESXi 6.0 + 6.5 with a 6.5 VCSA that is TLS 1.2 only. 
#>


# What is the vCenter and ESXI FQDN?
$vCenter = Read-Host "Enter the vCenter Name"
$esxihostname = Read-Host "Enter the FQDN of the ESXi host that is in maintenance mode"

# Connect to your vCenter
Connect-VIServer $vCenter 

Function Set-ESXiDPC {
    <#
        .NOTES
        ===========================================================================
         Created by:    William Lam
         Organization:  VMware
         Blog:          www.virtuallyghetto.com
         Twitter:       @lamw
            ===========================================================================
        .DESCRIPTION
            This function configures the TLS protocols to disable for all 
            ESXi hosts within a vSphere Cluster
        .SYNOPSIS
            Configures the disabled TLS protocols for Hostd, Authd, sfcbd & VSANVP/IOFilter 
        .PARAMETER Cluster
            The name of the vSphere Cluster
        .EXAMPLE
            Set-ESXiDPC -Cluster VSAN-Cluster -TLS1 $true -TLS1_1 $true -TLS1_2 $false -SSLV3 $true
    #>
        param(
            [Parameter(Mandatory=$true)][Boolean]$TLS1,
            [Parameter(Mandatory=$true)][Boolean]$TLS1_1,
            [Parameter(Mandatory=$true)][Boolean]$TLS1_2,
            [Parameter(Mandatory=$true)][Boolean]$SSLV3
        )

        Function UpdateSFCBConfig {
            param(
                [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl]$VMHost
            )

            $url = "https://$vmhost/host/sfcb.cfg"

            $sessionManager = Get-View ($global:DefaultVIServer.ExtensionData.Content.sessionManager)

            $spec = New-Object VMware.Vim.SessionManagerHttpServiceRequestSpec
            $spec.Method = "httpGet"
            $spec.Url = $url
            $ticket = $sessionManager.AcquireGenericServiceTicket($spec)

            $websession = New-Object Microsoft.PowerShell.Commands.WebRequestSession
            $cookie = New-Object System.Net.Cookie
            $cookie.Name = "vmware_cgi_ticket"
            $cookie.Value = $ticket.id
            $cookie.Domain = $vmhost.name
            $websession.Cookies.Add($cookie)
            $result = Invoke-WebRequest -Uri $url -WebSession $websession
            $sfcbConf = $result.content

            # Download the current sfcb.cfg and ignore existing TLS configuration
            $sfcbResults = ""
            foreach ($line in $sfcbConf.Split("`n")) {
                if($line -notmatch "enableTLSv1:" -and $line -notmatch "enableTLSv1_1:" -and $line -notmatch "enableTLSv1_2:" -and $line -ne "") {
                    $sfcbResults+="$line`n"
                }
            }

            # Append the TLS protocols based on user input to the configuration file
            $sfcbResults+="enableTLSv1: " + (!$TLS1).ToString().ToLower() + "`n"
            $sfcbResults+="enableTLSv1_1: " + (!$TLS1_1).ToString().ToLower() + "`n"
            $sfcbResults+="enableTLSv1_2: " + (!$TLS1_2).ToString().ToLower() +"`n"

            # Create HTTP PUT spec
            $spec.Method = "httpPut"
            $spec.Url = $url
            $ticket = $sessionManager.AcquireGenericServiceTicket($spec)

            # Upload sfcb.cfg back to ESXi host
            $websession = New-Object Microsoft.PowerShell.Commands.WebRequestSession
            $cookie.Name = "vmware_cgi_ticket"
            $cookie.Value = $ticket.id
            $cookie.Domain = $vmhost.name
            $websession.Cookies.Add($cookie)
            $result = Invoke-WebRequest -Uri $url -WebSession $websession -Body $sfcbResults -Method Put -ContentType "plain/text"
            if($result.StatusCode -eq 200) {
                Write-Host "`tSuccessfully updated sfcb.cfg file"
            } else {
                Write-Host "Failed to upload sfcb.cfg file"
                break
            }
        }

        # Build TLS string based on user input for setting ESXi Advanced Settings
        if($TLS1 -and $TLS1_1 -and $TLS1_2 -and $SSLV3) {
            Write-Host -ForegroundColor Red "Error: You must at least enable one of the TLS protocols"
            break
        }

        $tlsString = @()
        if($TLS1) { $tlsString += "tlsv1" }
        if($TLS1_1) { $tlsString += "tlsv1.1" }
        if($TLS1_2) { $tlsString += "tlsv1.2" }
        if($SSLV3) { $tlsString += "sslv3" }
        $tlsString = $tlsString -join ","

        Write-Host "`nDisabling the following TLS protocols: $tlsString on ESXi host ...`n"
        $vmhost = Get-VMHost -Name $esxihostname
        if($vmhost.State -eq "Maintenance"){	
            if( ($vmhost.ApiVersion -eq "6.0" -and (Get-AdvancedSetting -Entity $vmhost -Name "Misc.HostAgentUpdateLevel").value -eq "3") -or ($vmhost.ApiVersion -eq "6.5") ) {
                Write-Host "Updating $vmhost ..."

                Write-Host "`tUpdating sfcb.cfg ..."
                UpdateSFCBConfig -vmhost $vmhost

                if($vmhost.ApiVersion -eq "6.0") {
                    Write-Host "`tUpdating UserVars.ESXiRhttpproxyDisabledProtocols ..."
                    Get-AdvancedSetting -Entity $vmhost -Name "UserVars.ESXiRhttpproxyDisabledProtocols" | Set-AdvancedSetting -Value $tlsString -Confirm:$false | Out-Null

                    Write-Host "`tUpdating UserVars.VMAuthdDisabledProtocols ..."
                    Get-AdvancedSetting -Entity $vmhost -Name "UserVars.VMAuthdDisabledProtocols" | Set-AdvancedSetting -Value $tlsString -Confirm:$false | Out-Null
                }
                Write-Host "`tUpdating UserVars.ESXiVPsDisabledProtocols ..."
                Get-AdvancedSetting -Entity $vmhost -Name "UserVars.ESXiVPsDisabledProtocols" | Set-AdvancedSetting -Value $tlsString -Confirm:$false | Out-Null
                Write-Host " "
                Write-Host "SUCCESS! Reboot ESXi host $esxihostname " -ForegroundColor "Green"
            }
        }
        else
        {
        Write-Host " "
        Write-Host "--> FAIL <--" -ForegroundColor "Red"
        Write-Host ($vmhost.Name + " " + "is NOT in maintenance mode.  Please enter maintenance mode and try again.") -ForegroundColor "Red"
        }

        }

# Disable TLS 1.0 1.1 & SSL V3 
Set-ESXiDPC -TLS1 $true -TLS1_1 $true -TLS1_2 $false -SSLV3 $true

# Disconnect from the vCenter
Disconnect-VIServer $vCenter -Confirm:$false
Setup

The PowerCLI script takes Function Set-ESXiDPC from https://github.com/lamw/vghetto-scripts/blob/master/powershell/ESXiDisableProtocolConfiguration.ps1 (via Cluster) but makes sure the single ESXi host in is maintenance mode.   The script was tested on ESXi 6.0 + 6.5 with a 6.5 VCSA that is TLS 1.2 only.

OpenSSL Test

Download Win32 OpenSSL v1.1.0g Light https://slproweb.com/products/Win32OpenSSL.html

 

Test TCP port 443 over TLS 1.0 and 1.1 before and after the reboot (yes, there are other ports that can be tested)
openssl.exe s_client -connect esxi-vsan1.my.lab:443 -tls1
openssl.exe s_client -connect esxi-vsan1.my.lab:443 -tls1_1

 

PowerCLI Script
<#
https://vmscribble.com PowerCLI 6.5.4
Pulled Nov 29, 2017 https://github.com/lamw/vghetto-scripts/blob/master/powershell/ESXiDisableProtocolConfiguration.ps1 The PowerCLI script takes Function Set-ESXiDPC (via Cluster) but makes sure the single ESXi host in is maintenance mode.
The script was tested on ESXi 6.0 + 6.5 with a 6.5 VCSA that is TLS 1.2 only. 
#>


# What is the vCenter and ESXI FQDN?
$vCenter = Read-Host "Enter the vCenter Name"
$esxihostname = Read-Host "Enter the FQDN of the ESXi host that is in maintenance mode"

# Connect to your vCenter
Connect-VIServer $vCenter 

Function Set-ESXiDPC {
    <#
        .NOTES
        ===========================================================================
         Created by:    William Lam
         Organization:  VMware
         Blog:          www.virtuallyghetto.com
         Twitter:       @lamw
            ===========================================================================
        .DESCRIPTION
            This function configures the TLS protocols to disable for all 
            ESXi hosts within a vSphere Cluster
        .SYNOPSIS
            Configures the disabled TLS protocols for Hostd, Authd, sfcbd & VSANVP/IOFilter 
        .PARAMETER Cluster
            The name of the vSphere Cluster
        .EXAMPLE
            Set-ESXiDPC -Cluster VSAN-Cluster -TLS1 $true -TLS1_1 $true -TLS1_2 $false -SSLV3 $true
    #>
        param(
            [Parameter(Mandatory=$true)][Boolean]$TLS1,
            [Parameter(Mandatory=$true)][Boolean]$TLS1_1,
            [Parameter(Mandatory=$true)][Boolean]$TLS1_2,
            [Parameter(Mandatory=$true)][Boolean]$SSLV3
        )

        Function UpdateSFCBConfig {
            param(
                [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl]$VMHost
            )

            $url = "https://$vmhost/host/sfcb.cfg"

            $sessionManager = Get-View ($global:DefaultVIServer.ExtensionData.Content.sessionManager)

            $spec = New-Object VMware.Vim.SessionManagerHttpServiceRequestSpec
            $spec.Method = "httpGet"
            $spec.Url = $url
            $ticket = $sessionManager.AcquireGenericServiceTicket($spec)

            $websession = New-Object Microsoft.PowerShell.Commands.WebRequestSession
            $cookie = New-Object System.Net.Cookie
            $cookie.Name = "vmware_cgi_ticket"
            $cookie.Value = $ticket.id
            $cookie.Domain = $vmhost.name
            $websession.Cookies.Add($cookie)
            $result = Invoke-WebRequest -Uri $url -WebSession $websession
            $sfcbConf = $result.content

            # Download the current sfcb.cfg and ignore existing TLS configuration
            $sfcbResults = ""
            foreach ($line in $sfcbConf.Split("`n")) {
                if($line -notmatch "enableTLSv1:" -and $line -notmatch "enableTLSv1_1:" -and $line -notmatch "enableTLSv1_2:" -and $line -ne "") {
                    $sfcbResults+="$line`n"
                }
            }

            # Append the TLS protocols based on user input to the configuration file
            $sfcbResults+="enableTLSv1: " + (!$TLS1).ToString().ToLower() + "`n"
            $sfcbResults+="enableTLSv1_1: " + (!$TLS1_1).ToString().ToLower() + "`n"
            $sfcbResults+="enableTLSv1_2: " + (!$TLS1_2).ToString().ToLower() +"`n"

            # Create HTTP PUT spec
            $spec.Method = "httpPut"
            $spec.Url = $url
            $ticket = $sessionManager.AcquireGenericServiceTicket($spec)

            # Upload sfcb.cfg back to ESXi host
            $websession = New-Object Microsoft.PowerShell.Commands.WebRequestSession
            $cookie.Name = "vmware_cgi_ticket"
            $cookie.Value = $ticket.id
            $cookie.Domain = $vmhost.name
            $websession.Cookies.Add($cookie)
            $result = Invoke-WebRequest -Uri $url -WebSession $websession -Body $sfcbResults -Method Put -ContentType "plain/text"
            if($result.StatusCode -eq 200) {
                Write-Host "`tSuccessfully updated sfcb.cfg file"
            } else {
                Write-Host "Failed to upload sfcb.cfg file"
                break
            }
        }

        # Build TLS string based on user input for setting ESXi Advanced Settings
        if($TLS1 -and $TLS1_1 -and $TLS1_2 -and $SSLV3) {
            Write-Host -ForegroundColor Red "Error: You must at least enable one of the TLS protocols"
            break
        }

        $tlsString = @()
        if($TLS1) { $tlsString += "tlsv1" }
        if($TLS1_1) { $tlsString += "tlsv1.1" }
        if($TLS1_2) { $tlsString += "tlsv1.2" }
        if($SSLV3) { $tlsString += "sslv3" }
        $tlsString = $tlsString -join ","

        Write-Host "`nDisabling the following TLS protocols: $tlsString on ESXi host ...`n"
        $vmhost = Get-VMHost -Name $esxihostname
        if($vmhost.State -eq "Maintenance"){	
            if( ($vmhost.ApiVersion -eq "6.0" -and (Get-AdvancedSetting -Entity $vmhost -Name "Misc.HostAgentUpdateLevel").value -eq "3") -or ($vmhost.ApiVersion -eq "6.5") ) {
                Write-Host "Updating $vmhost ..."

                Write-Host "`tUpdating sfcb.cfg ..."
                UpdateSFCBConfig -vmhost $vmhost

                if($vmhost.ApiVersion -eq "6.0") {
                    Write-Host "`tUpdating UserVars.ESXiRhttpproxyDisabledProtocols ..."
                    Get-AdvancedSetting -Entity $vmhost -Name "UserVars.ESXiRhttpproxyDisabledProtocols" | Set-AdvancedSetting -Value $tlsString -Confirm:$false | Out-Null

                    Write-Host "`tUpdating UserVars.VMAuthdDisabledProtocols ..."
                    Get-AdvancedSetting -Entity $vmhost -Name "UserVars.VMAuthdDisabledProtocols" | Set-AdvancedSetting -Value $tlsString -Confirm:$false | Out-Null
                }
                Write-Host "`tUpdating UserVars.ESXiVPsDisabledProtocols ..."
                Get-AdvancedSetting -Entity $vmhost -Name "UserVars.ESXiVPsDisabledProtocols" | Set-AdvancedSetting -Value $tlsString -Confirm:$false | Out-Null
                Write-Host " "
                Write-Host "SUCCESS! Reboot ESXi host $esxihostname " -ForegroundColor "Green"
            }
        }
        else
        {
        Write-Host " "
        Write-Host "--> FAIL <--" -ForegroundColor "Red"
        Write-Host ($vmhost.Name + " " + "is NOT in maintenance mode.  Please enter maintenance mode and try again.") -ForegroundColor "Red"
        }

        }

# Disable TLS 1.0 1.1 & SSL V3 
Set-ESXiDPC -TLS1 $true -TLS1_1 $true -TLS1_2 $false -SSLV3 $true

# Disconnect from the vCenter
Disconnect-VIServer $vCenter -Confirm:$false