- Reading Azure VM name, IP address, and hostname with PowerShell - Fri, Jul 28 2017
- Automating WSUS with PowerShell - Thu, Jul 13 2017
- Disable SSL and TLS 1.0/1.1 on IIS with PowerShell - Tue, Jun 27 2017
Take a look at the script before I start explaining how it works.
[CmdletBinding()] Param( [Parameter(Mandatory=$True)] [ValidateSet("SSL30","TLS10","TLS11","TLS12")] [string]$Proto, [ValidateSet("Client","Server")] [string]$Target, [Parameter(Mandatory=$True)] [ValidateSet("Enable","Disable")] $Action) Function CheckKey{ param( [string]$Proto ) $RegKey = $null switch ($Proto){ SSL30 {$RegKey = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0"} TLS10 {$RegKey = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0"} TLS11 {$RegKey = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1"} TLS12 {$RegKey = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2"} default{"Not supported protocol. Possible values: SSL30, TLS10, TLS11, TLS12" exit} } return $Regkey } $RegKey = CheckKey -Proto $Proto [string[]]$TargetKey = $null if(!($Target)){ Write-Host "Setting up both Client and Server protocols" $TargetKey = $(Join-Path $RegKey "Client").ToString() $TargetKey += $(Join-Path $RegKey "Server").ToString() if(!(Test-path -Path $TargetKey[0])){ New-Item $TargetKey[0] -Force } if(!(Test-path -Path $TargetKey[1])){ New-Item $TargetKey[1] -Force } } else{ Write-Host "Setting up $Target protocols" $TargetKey = $(Join-Path $RegKey $Target).ToString() if(!(Test-path -Path $(Join-Path $RegKey $Target))){ New-Item $TargetKey -Force } } Function SetProto{ param( [string[]]$TargetKey, [string]$Action ) foreach($key in $TargetKey){ try{ Get-ItemProperty -Path $key -Name "Enabled" -ErrorAction Stop | Out-Null if($Action -eq "Disable"){ Write-Host "`t`Updating $key" Set-ItemProperty -Path $key -Name "Enabled" -Value 0 -Type "DWord" } else{ Write-Host "`t`Updating $key" Set-ItemProperty -Path $key -Name "Enabled" -Value 1 -Type "DWord" } }Catch [System.Management.Automation.PSArgumentException]{ if($Action -eq "Disable"){ Write-Host "`t`Creating $key" New-ItemProperty -Path $key -Name "Enabled" -Value 0 -PropertyType "DWord" } else{ Write-Host "`t`Creating $key" New-ItemProperty -Path $key -Name "Enabled" -Value 1 -PropertyType "DWord" } } try{ Get-ItemProperty -Path $key -Name "DisabledByDefault" -ErrorAction Stop | Out-Null if($Action -eq "Disable"){ Write-Host "`t`Updating $key" Set-ItemProperty -Path $key -Name "DisabledByDefault" -Value 1 -Type "DWord" } else{ Write-Host "`t`Updating $key" Set-ItemProperty -Path $key -Name "DisabledByDefault" -Value 0 -Type "DWord" } }Catch [System.Management.Automation.PSArgumentException]{ if($Action -eq "Disable"){ Write-Host "`t`Creating $key" New-ItemProperty -Path $key -Name "DisabledByDefault" -Value 1 -PropertyType "DWord" } else{ Write-Host "`t`Creating $key" New-ItemProperty -Path $key -Name "DisabledByDefault" -Value 0 -PropertyType "DWord" } } } } SetProto -TargetKey $TargetKey -Action $Action Write-Host "The operation completed successfully, reboot is required" -ForegroundColor Green
Because I don't want to edit the script text every time I run it, I've defined the parameters below.
[CmdletBinding()] Param( [Parameter(Mandatory=$True)] [ValidateSet("SSL30","TLS10","TLS11","TLS12")] [string]$Proto, [ValidateSet("Client","Server")] [string]$Target, [Parameter(Mandatory=$True)] [ValidateSet("Enable","Disable")]
The first parameter is for the four different protocols. To be sure, I added the ValidateSet option that restricts the parameter input to the four possible options. The Target parameter is optional and allows you to disable the protocols for client and server applications separately. Omitting this parameter will change both the client and server protocols. The last parameter is mandatory and determines whether to enable or disable the specified protocols.
The screenshot below shows what happens if you call the script with the wrong parameters.
You can disable and enable the protocols through registry keys. The function below defines the corresponding variables depending on the protocol settings you want to change.
Function CheckKey{ param( [string]$Proto ) $RegKey = $null switch ($Proto){ SSL30 {$RegKey = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0"} TLS10 {$RegKey = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0"} TLS11 {$RegKey = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1"} TLS12 {$RegKey = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2"} default{"Not supported protocol. Possible values: SSL30, TLS10, TLS11, TLS12" exit} } return $Regkey }
The next snippet determines whether I have to change the settings for the client or server or both.
<in$RegKey = CheckKey -Proto $Proto [string[]]$TargetKey = $null if(!($Target)){ Write-Host "Setting up both client and server protocols" $TargetKey = $(Join-Path $RegKey "Client").ToString() $TargetKey += $(Join-Path $RegKey "Server").ToString() if(!(Test-path -Path $TargetKey[0])){ New-Item $TargetKey[0] -Force } if(!(Test-path -Path $TargetKey[1])){ New-Item $TargetKey[1] -Force } } else{ Write-Host "Setting up $Target protocols" $TargetKey = $(Join-Path $RegKey $Target).ToString() if(!(Test-path -Path $(Join-Path $RegKey $Target))){ New-Item $TargetKey -Force } }
With the help of the Join-Path cmdlet, I combine the registry path with the target (client or server) and save the corresponding registry key in the $Targetkey variable. With the Test-Path cmdlet, I determine whether the key exists, and if not I create it. After executing this piece of code, I have the $Targetkey string array, which consist of either one or two values (client or server, or both).
The next function then changes the protocol settings in the registry.
Function SetProto{ param( [string[]]$TargetKey, [string]$Action ) foreach($key in $TargetKey){ try{ Get-ItemProperty -Path $key -Name "Enabled" -ErrorAction Stop | Out-Null if($Action -eq "Disable"){ Write-Host "`t`Updating $key" Set-ItemProperty -Path $key -Name "Enabled" -Value 0 -Type "DWord" } else{ Write-Host "`t`Updating $key" Set-ItemProperty -Path $key -Name "Enabled" -Value 1 -Type "DWord" } }Catch [System.Management.Automation.PSArgumentException]{ if($Action -eq "Disable"){ Write-Host "`t`Creating $key" New-ItemProperty -Path $key -Name "Enabled" -Value 0 -PropertyType "DWord" } else{ Write-Host "`t`Creating $key" New-ItemProperty -Path $key -Name "Enabled" -Value 1 -PropertyType "DWord" } } try{ Get-ItemProperty -Path $key -Name "DisabledByDefault" -ErrorAction Stop | Out-Null if($Action -eq "Disable"){ Write-Host "`t`Updating $key" Set-ItemProperty -Path $key -Name "DisabledByDefault" -Value 1 -Type "DWord" } else{ Write-Host "`t`Updating $key" Set-ItemProperty -Path $key -Name "DisabledByDefault" -Value 0 -Type "DWord" } }Catch [System.Management.Automation.PSArgumentException]{ if($Action -eq "Disable"){ Write-Host "`t`Creating $key" New-ItemProperty -Path $key -Name "DisabledByDefault" -Value 1 -PropertyType "DWord" } else{ Write-Host "`t`Creating $key" New-ItemProperty -Path $key -Name "DisabledByDefault" -Value 0 -PropertyType "DWord" } } } } SetProto -TargetKey $TargetKey -Action $Action Write-Host "The operation completed successfully, reboot is required" -ForegroundColor Green
The function accepts the $Targetkey string array and the $Action variable as parameters. I'm going through every registry key stored in the $Targetkey array using a foreach loop to do the steps below.
First I try to get the "Enabled" value from the key. If this succeeds and if $Action is equal to "Disable," I assign "0" to the registry key stored in the $Targetkey array. This disables the security protocol that the $Proto parameter specifies. If $Action is not equal to "Disable," I assign "1" to enable the protocol.
And if I can't get the "Enabled" key name from the path stored in the $Targetkey array, it throws the System.Management.Automation.PSArgumentException. I catch this exception, and since I know there is no "Enabled" key name, I can create the key and assign the appropriate value depending on the contents of the $Action variable.
The second try-catch block does essentially the same thing, only it changes the DisabledByDefault key. The two keys Enabled and DisabledByDefault have opposite values. Thus, when Enabled is "0" DisabledByDefault is "1" and vice versa.
And finally, I call the SetProto function and notify the user that a reboot is required to apply the changes.
The screenshots below show the console output of the script:
Thanks Alex,
I have tested your script and very useful, Is it possible to display the current settings first and give Options like radio button or Popup box to Enable/Disable specific or Default settings.
Good stuff. Very useful
Perfect!