Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Downloads IISCrypto cli, uses custom template based on bestpractice, to fix ssl security on servers, enables http2 on win2k16 server and grade A+ in qualys ssl server test if using TLS1.2 only template
# 2018-08-17 reintroduced templates for 2012 with ciphers: 0x9C, 0x9D they are considered weak, but are the only AEAD ciphers available for 2012 atm.
# updated 2018-08-16 with some extra steps like enabling OCSP for SNI, added TLS1.2 only option for pre win2k16 aswell, added check to see if HTTP/2 was disabled.
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Write-Host "Starting as administrator and using Bypass ExecutionPolicy.";Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs; exit }
# Go to a location we have write access to.
Set-Location ~\Downloads
# Global variables and settings.
[System.Net.ServicePointManager]::SecurityProtocol = 192 -bor 768 -bor 3072 # .Net doesn't enable tls1.1 and 1.2 by default, but can run it as long as .net 4.5 is installed. Which we need to download from sites that only allows tls1.2
$icDownloadUrl = ""
$icDownloadName = "IISCryptoCli.exe"
$templateName = "template.ictpl"
$templateUrl_2016_tls12only = ""
$templateUrl_2016_broad = ""
$templateUrl_pre2016_broad = ""
$templateUrl_pre2016_tls12only = ""
$ocspRegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\"
$oscpForSni = "EnableOcspStaplingForSni"
if(-Not (Test-Path -Path $icDownloadName)) {
Write-Host "Downloading IIS Crypto tool." -ForegroundColor Green
iwr -UseBasicParsing -Uri $icDownloadUrl -OutFile $icDownloadName
$chType = [System.Management.Automation.Host.ChoiceDescription]
$broadSupport = New-Object $chType "&Broad Support","Uses template with TLS 1.0 and TLS 1.1 support for broad backwards compatability"
$bestSecurity = New-Object $chType "Best &Security","Only enables TLS 1.2 protocol, this gives an A+ security rating for qualsys server test, but removes support for old systems that only run TLS 1.0/1.1 like: Android pre. 4.4.2, Baidu Jan 2015, IE<=10, Java<=7u25, OpenSSL<=0.9.8y, Safari 7 on OS X 10.8. more details:"
$templateOptions = [System.Management.Automation.Host.ChoiceDescription[]]($bestSecurity, $broadSupport)
$templateResult = $host.ui.PromptForChoice("Security settings", "Do you want to use a broader template supporting TLS 1.0/1.1 or a more secure template only supporting TLS 1.2 (and ability to get A+ grade on IIS server with HSTS enabled)", $templateOptions, 0)
Write-Host "Downloading selected security template." -ForegroundColor Green
$isWin2k16 = (gwmi win32_operatingsystem | % caption) -like "Microsoft Windows Server 2016*"
if($templateResult -eq 0)
iwr -UseBasicParsing -Uri $templateUrl_2016_tls12only -OutFile $templateName
} else {
iwr -UseBasicParsing -Uri $templateUrl_2016_broad -OutFile $templateName
} else {
if($templateResult -eq 0)
iwr -UseBasicParsing -Uri $templateUrl_pre2016_tls12only -OutFile $templateName
} else {
iwr -UseBasicParsing -Uri $templateUrl_pre2016_broad -OutFile $templateName
Write-Host "IIS Crypto is applying selected template." -ForegroundColor Green
Start-Process -FilePath ".\$icDownloadName" -ArgumentList "/template",".\$templateName" -NoNewWindow -PassThru -Wait | out-null
# Cleanup
ri -Path $icDownloadName,$templateName -Confirm
$schannel = gi -Path "$ocspRegPath"
if($schannel.GetValue($oscpForSni) -eq $null -Or $schannel.GetValue($oscpForSni) -eq 0)
# ask to add OCSP for SNI
$oscp_yes = New-Object $chType "&Yes","Creates a scheduled task to run once tomorrow at 03:00 local time."
$oscp_no = New-Object $chType "&No","Exits the powershell script."
$oscp_options = [System.Management.Automation.Host.ChoiceDescription[]]($oscp_yes, $oscp_no)
$oscp_result = $host.ui.PromptForChoice("Enable OCSP Stapling for SNI:", "OCSP Stapling for SNI is currently disabled. Enabling this could provide performance benefits for HTTPS, unless you are using many ( > 100 ) certificates. More info:", $oscp_options, 0)
switch ($oscp_result)
0 {
Write-Host "Creating OCSP Stapling for SNI registry key. ($ocspRegPath $oscpForSni)" -ForegroundColor Green
New-ItemProperty -Path "$ocspRegPath" -Name "$oscpForSni" -Value 1 -PropertyType DWord -Force | out-null
else {
Write-Host "Skipped."
} else {
Write-Host "OCSP Stapling for SNI is already enabled." -ForegroundColor Green
# check if HTTP/2 is disabled.
$http2Path = gi -Path "HKLM:\System\CurrentControlSet\Services\HTTP\Parameters"
$http2key1 = "EnableHttp2Tls"
$http2key2 = "EnableHttp2Cleartext"
if($isWin2k16 -And (($http2Path.GetValue($http2key1) -ne $null -And $http2Path.GetValue($http2key1) -eq 1) -Or ($http2Path.GetValue($http2key2) -ne $null -And $http2Path.GetValue($http2key2) -eq 1)))
Write-Host "Http/2 is currently disabled on your server, this might not be intended and isn't recommended." -ForegroundColor Green
$yes = New-Object $chType "&Yes","Creates a scheduled task to run once tomorrow at 03:00 local time."
$no = New-Object $chType "&No","Exits the powershell script."
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
$result = $host.ui.PromptForChoice("ScheduledTask to Restart-Computer:", "Do you want to create a scheduled task to restart the computer?", $options, 0)
$taskName = "FixSSLSecurity-OneTimeRestartJob"
$taskTriggerTime = (Get-Date).Date.AddDays(1).AddHours(3)
switch ($result) {
0 {
Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue -OutVariable existingTask | out-null
if($existingTask) {
$newTime = New-ScheduledTaskTrigger -Once -At $taskTriggerTime
Set-ScheduledTask -TaskName $taskName -Trigger $newTime | out-null
Write-Host "$taskName Exists. Task trigger restart time set to:" (Get-Date -Date $taskTriggerTime -Format f)
} else {
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "Restart-Computer"
$trigger = New-ScheduledTaskTrigger -Once -At $taskTriggerTime
$principal = New-ScheduledTaskPrincipal "SYSTEM" -RunLevel Highest
$task = New-ScheduledTask -Action $action -Trigger $trigger -Principal $principal
Try {
Register-ScheduledTask $taskName -InputObject $task -ErrorAction Stop | out-null
Write-Host "$taskName Created. Computer will restart once, at:" (Get-Date -Date $taskTriggerTime -Format f)
} Catch {
Write-Host "Error, could not create ScheduledTask:" $_.Exception.Message
1 { "No Scheduled task created. Remember to schedule a restart of the server for changes to take effect!" }
Write-Host "Press any key to close ..." -ForegroundColor Green
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.