Skip to content

Instantly share code, notes, and snippets.

@gitfvb
Last active September 29, 2021 20:50
Show Gist options
  • Select an option

  • Save gitfvb/4029bac8c4a890d7cb0f30496ff24ce7 to your computer and use it in GitHub Desktop.

Select an option

Save gitfvb/4029bac8c4a890d7cb0f30496ff24ce7 to your computer and use it in GitHub Desktop.
change certificate for rdp to let's encrypt (or other) certificates
# copy the certificate from "Web Hosting\Certificates" to "Personal\Certificates" and then execute this command with changed "<FINGERPRINT>"
# note: the SHA1 fingerprint should be without spaces and with capital letters
wmic /namespace:\\root\cimv2\TerminalServices PATH Win32_TSGeneralSetting Set SSLCertificateSHA1Hash="<FINGERPRINT>"
# This script works when executed in single parts.... if the certificate is expired, it needs to create a new one and this need a temporary dns txt entry where the key is generated through this script. When it is created succesfully, all the other steps work fine here
# debug switch
$debug = $false
# settings
$dns = "crm.apteco.io"
$destCertPath = "Cert:\LocalMachine\My" #"Cert:\LocalMachine\Remote Desktop" #"Cert:\LocalMachine\WebHosting" # https://serverfault.com/questions/710293/wmic-error-when-setting-remote-desktop-self-signed-certificate
$email = "[email protected]"
$renewalBeforeExpiration = 14 # days
# Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force
Import-Module Posh-ACME
# Create a new one if in debug mode
if ( $debug ) {
# Create new certificate
# For the new creation it would be helpful that the script can set the dns txt entry itself (and remove it), but this API is still in beta on IONOS side
# This is created to: %LOCALAPPDATA%\Posh-ACME
$cert = New-PACertificate $dns -AcceptTOS -Contact $email
} else {
# Details for last certificate
$cert = Get-PACertificate | select -first 1 # #| where { $_.Thumbprint -eq "EBECC8ADB9A2EB194D02B31967601DE8331A5D95" }#$cert.Thumbprint }
#Submit-Renewal
}
# Age of last certificate
$ts = New-TimeSpan -End $cert.NotAfter -Start ([datetime]::Today)
# Create a new certificate if less than n days
If ( $ts.Days -lt $renewalBeforeExpiration ) {
$cert = Submit-Renewal -Force -NoSkipManualDns
}
# Import the certificate
Set-Location -Path $destCertPath
$cer = Import-PfxCertificate -Password $cert.PfxPass -FilePath $cert.PfxFullChain #$cert.PfxFile
# Read the private key
$rsaCert = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($cer)
# Check the cert folder after import
#$SslCertificate = Get-ChildItem -Path $destCertPath | where { $_.NotBefore -lt [datetime]::now -and $_.NotAfter -gt [datetime]::now -and $_.Subject -match $dns } | Sort $_.NotAfter -descending | Select -First 1
# Change back to file system
Set-Location -Path $env:USERPROFILE
$TSGS = Get-WmiObject -Class "Win32_TSGeneralSetting" -Namespace "root\cimv2\terminalservices"
Set-WmiInstance -Path $TSGS -Arguments @{SSLCertificateSHA1Hash=$cert.Thumbprint.ToString()}
# Give access to the private key file for NETWORK SERVICE
$filename = $rsaCert.key.uniquename
$path = "$( $env:ALLUSERSPROFILE )\Microsoft\Crypto\Keys\$( $filename )"
icacls $path /grant "NT Authority\NETWORK SERVICE:F"
# Restart services
ReStart-Service -Force -Name SessionEnv
Restart-Service -Force -Name TermService
exit 0
# copy the certificate from "Web Hosting\Certificates" to "Personal\Certificates" and then execute this command with changed "<FINGERPRINT>"
# note: the SHA1 fingerprint should be without spaces and with capital letters
#wmic /namespace:\\root\cimv2\TerminalServices PATH Win32_TSGeneralSetting Set SSLCertificateSHA1Hash=EBECC8ADB9A2EB194D02B31967601DE8331A5D95
#wmic /namespace:\\root\cimv2\TerminalServices PATH Win32_TSGeneralSetting Set SSLCertificateSHA1Hash=$cert.Thumbprint
#wmic /namespace:\\root\cimv2\TerminalServices PATH Win32_TSGeneralSetting Set SSLCertificateSHA1Hash=84485E19C85D1F607865D49A924A73301EE9D529
#Stop-Service -Name SessionEnv
#ReStart-Service -Force -Name SessionEnv
#Restart-Service -Force -Name TermService
@gitfvb
Copy link
Author

gitfvb commented Dec 15, 2020

Using another dns entry to allow a non-public server to create the certificate with posh-acme:
Create the request first
grafik

@gitfvb
Copy link
Author

gitfvb commented Dec 15, 2020

grafik

@gitfvb
Copy link
Author

gitfvb commented Dec 15, 2020

This can help, too


# settings
$dns = "crm.apteco.io"
$sourceCertPath = "Cert:\LocalMachine\My\" #"Cert:\LocalMachine\WebHosting"
#$destinationCertPath = "Cert:\LocalMachine\My"
#$tempCert = "$( [Environment]::GetEnvironmentVariable("temp") )\$( ( [guid]::NewGuid() ).Guid ).cer"

# I assume a certificate for the webhosting already exists
# List all matching and valid certificates and pick a valid and long lasting one
$SslCertificate = Get-ChildItem -Path $sourceCertPath | where { $_.NotBefore -lt [datetime]::now -and $_.NotAfter -gt [datetime]::now -and $_.Subject -match $dns } | Sort $_.NotAfter -descending | Select -First 1


#$thumbprint = (Get-ChildItem -Path 'Cert:\LocalMachine\My\').Thumbprint
wmic /namespace:\\root\cimv2\TerminalServices PATH Win32_TSGeneralSetting Set SSLCertificateSHA1Hash=$thumbprint

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment