Skip to content

Instantly share code, notes, and snippets.

@anthonyeden
Created October 28, 2017 02:59
Show Gist options
  • Star 17 You must be signed in to star a gist
  • Fork 10 You must be signed in to fork a gist
  • Save anthonyeden/710d63247d9b6b9202a11bf00b146c01 to your computer and use it in GitHub Desktop.
Save anthonyeden/710d63247d9b6b9202a11bf00b146c01 to your computer and use it in GitHub Desktop.
Let's Encrypt & Microsoft Remote Desktop Services - Installation Script
"C:\Program Files\Lets Encrypt\letsencrypt.exe" --renew --baseuri "https://acme-v01.api.letsencrypt.org/"
powershell -File "C:\Program Files\Lets Encrypt\RDS_INSTALL_CERT.ps1" -CertificateImport "C:\ProgramData\letsencrypt-win-simple\httpsacme-v01.api.letsencrypt.org\remote.example.com-all.pfx" -RDCB remote.example.com
# Install a Let's Encrypt certificate to Remote Desktop Services
# Hacked together by Anthony Eden (https://mediarealm.com.au/)
#Credit: https://ryanmangansitblog.com/2014/06/17/deploying-rds-2012-wild-card-certificate-using-powershell/
#Credit: https://github.com/Lone-Coder/letsencrypt-win-simple/issues/400
param (
[Parameter(Mandatory=$TRUE, HelpMessage="store the certificate localy (c:\)")]
[String]
$CertificateImport,
[Parameter(Mandatory=$TRUE, HelpMessage="Connection Broker FQDN")]
[String]
$RDCB
)
if ( ((get-date) - (ls $CertificateImport).LastWriteTime).minutes -gt 10){ exit }
# This is where a temporary certificate will be stored (we delete it at the end)
$tempPfxPath = 'C:\ProgramData\letsencrypt-win-simple\temp-pfx.pfx'
# Import the RemoteDesktop module
Import-Module RemoteDesktop
# Create the temporary certificate
$newCertPfx = Import-PfxCertificate -FilePath $CertificateImport -CertStoreLocation Cert:\LocalMachine\My -Exportable
$tempPasswordPfx = ConvertTo-SecureString -String "TemporaryPassword" -Force -AsPlainText
Export-PfxCertificate -cert $newCertPfx -FilePath $tempPfxPath -Force -NoProperties -Password $tempPasswordPfx
Remove-Item -Path $newCertPfx.PSPath
# Configure RDPublishing Certificate for RDS
set-RDCertificate -Role RDPublishing `
-ImportPath $tempPfxPath `
-Password $tempPasswordPfx `
-ConnectionBroker $RDCB -Force `
# Configure First RDWebAccess Certificate for RDS
set-RDCertificate -Role RDWebAccess `
-ImportPath $tempPfxPath `
-Password $tempPasswordPfx `
-ConnectionBroker $RDCB -Force `
# Configure Second Certificate for RDS
set-RDCertificate -Role RDWebAccess `
-ImportPath $tempPfxPath `
-Password $tempPasswordPfx `
-ConnectionBroker $RDCB -Force `
# Configure RDRedirector Certificate for RDS
set-RDCertificate -Role RDRedirector `
-ImportPath $tempPfxPath `
-Password $tempPasswordPfx `
-ConnectionBroker $RDCB -force `
# Configure First RDGateway Certificate for RDS
set-RDCertificate -Role RDGateway `
-ImportPath $tempPfxPath `
-Password $tempPasswordPfx `
-ConnectionBroker $RDCB -force `
# Configure Second RDGateway Certificate for RDS
set-RDCertificate -Role RDGateway `
-ImportPath $tempPfxPath `
-Password $tempPasswordPfx `
-ConnectionBroker $RDCB -force `
# Cleanup the temporary PFX file
Remove-Item -Path $tempPfxPath
@marco-itnetsys
Copy link

The data path has changed from C:\ProgramData\letsencrypt-win-simple to C:\ProgramData\win-acme breaking the temp file.

I propose fixing it by changing line 21 to:
$tempPfxPath = $env:TEMP + '\temp-pfx.pfx'

@GabrielFranca80
Copy link

dont work more =\ tested azure

@spchester
Copy link

Change like 21 to:
$tempPfxPath = 'C:\ProgramData\win-acme\temp-pfx.pfx'

You also have to change the URLs in the .bat file.

@DarrenChap
Copy link

Not sure but I think this line:
if ( ((get-date) - (ls $CertificateImport).LastWriteTime).minutes -gt 10){ exit }

Should be:
if ( ((get-date) - (ls $CertificateImport).LastWriteTime).TotalMinutes -gt 10){ exit }

@Natakugithub
Copy link

Natakugithub commented Jun 26, 2019

So I've been working through the script, here is a few things to change

  1. added the code below for param, mine had password, not sure if the old ones didn't
    [Parameter(Mandatory=$TRUE, HelpMessage="Certificate Password")] [String] $Password

  2. right after the param box add the code below to convert string password to secure password so that it can actually read it
    $Secure2 = ConvertTo-SecureString $Password -AsPlainText -Force

[Edit: oops missed a line of code. If the code lines are still the same it should be around 33. replace that line with the code below (27 in original)]
$newCertPfx = Import-PfxCertificate -FilePath $CertificateImport -Password $Secure2 -CertStoreLocation Cert:\LocalMachine\My -Exportable

  1. changed the check code from
    if ( ((get-date) - (ls $CertificateImport).LastWriteTime).minutes -gt 10){ exit }
    to
    if ( ((get-date) - (ls $CertificateImport).LastWriteTime).TotalMinutes -lt 10){ exit }

note I don't actually understand why this code is necessary, and in a way you can keep -gt but change the time. I just kept timing out and got exited the code, so a lot of room to play here

  1. change the path
    $tempPfxPath = 'C:\ProgramData\win-acme\temp-pfx.pfx'

  2. batch file should be changed to the following
    "C:\inetpub\letsencrypt\wacs.exe" --renew --baseuri "https://acme-v01.api.letsencrypt.org/" powershell -File "C:\Scripts\LetsEncrypt\RDS_INSTALL_CERT.ps1" -CertificateImport "C:\ProgramData\win-acme\acme-v02.api.letsencrypt.org\Certificates\<!------CertNameHere------!>.pfx" -RDCB <!------ServerNameHere------!> -Password "<!------CertPasswordHere------!>"

-File part can be adjusted to where you store the scripts
password can be found by running wacs.exe in the LetsEncrypt thingy and using the L option then the number for the certificate in question

@simonwhill
Copy link

simonwhill commented Jul 2, 2019

Hi @Natakugithub can you be clearer about where to place the $Secure2 = ConvertTo-SecureString $Password -AsPlainText -Force line and where the variable $Secure2 is referenced / used?

Also when i run the batch file i get the following error
`PS C:\Program Files\win-acme> ./RDS_Install_CERT.ps1 -CertificateImport "C:\ProgramData\win-acme\acme-v02.api.letsencrypt.org\Certificates\eS7DC6fcaE68-cache.pfx" -RDCB
xxxxxxx.xxxx.xxxx -Password "FUb4ko8YxM2gi0u/vFaOaDkYwOKy"
Import-PfxCertificate : The PFX file you are trying to import requires either a different password or membership in an Active Directory principal to which it is protected.
At C:\Program Files\win-acme\RDS_Install_CERT.ps1:32 char:15

  • ... ewCertPfx = Import-PfxCertificate -FilePath $CertificateImport -CertS ...
  •             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : NotSpecified: (:) [Import-PfxCertificate], Win32Exception
    • FullyQualifiedErrorId : System.ComponentModel.Win32Exception,Microsoft.CertificateServices.Commands.ImportPfxCertificate`

I'm running as the local domain administrator.

Thanks

Simon

@Natakugithub
Copy link

Natakugithub commented Jul 3, 2019

Hi @Natakugithub can you be clearer about where to place the $Secure2 = ConvertTo-SecureString $Password -AsPlainText -Force line and where the variable $Secure2 is referenced / used?
shortened
I'm running as the local domain administrator.
Thanks
Simon

oops, my bad. I missed a line of code, if the line number is still correct it should be around 33 (27 in original). I think that is the only that needs to be updated, here is the code

$newCertPfx = Import-PfxCertificate -FilePath $CertificateImport -Password $Secure2 -CertStoreLocation Cert:\LocalMachine\My -Exportable

@MonsterITServices
Copy link

Getting these error messages.
`Import-PfxCertificate : The PFX file you are trying to import requires either a different password or membership in an
Active Directory principal to which it is protected.
At C:\Program Files\Lets Encrypt\RDS_INSTALL_CERT.ps1:27 char:15

  • ... ewCertPfx = Import-PfxCertificate -FilePath $CertificateImport -CertS ...
  •             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : NotSpecified: (:) [Import-PfxCertificate], Win32Exception
    • FullyQualifiedErrorId : System.ComponentModel.Win32Exception,Microsoft.CertificateServices.Commands.ImportPfxCer
      tificate

Export-PfxCertificate : Cannot bind argument to parameter 'Cert' because it is null.
At C:\Program Files\Lets Encrypt\RDS_INSTALL_CERT.ps1:29 char:29

  • Export-PfxCertificate -cert $newCertPfx -FilePath $tempPfxPath -Force ...
  •                         ~~~~~~~~~~~
    
    • CategoryInfo : InvalidData: (:) [Export-PfxCertificate], ParameterBindingValidationException
    • FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.CertificateServices.Commands.Ex
      portPfxCertificate

Remove-Item : Cannot bind argument to parameter 'Path' because it is null.
At C:\Program Files\Lets Encrypt\RDS_INSTALL_CERT.ps1:30 char:19

  • Remove-Item -Path $newCertPfx.PSPath
  •               ~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidData: (:) [Remove-Item], ParameterBindingValidationException
    • FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.RemoveItemC
      ommand

set-RDCertificate : The specified path C:\ProgramData\letsencrypt-win-simple\temp-pfx.pfx is not valid or not
accessible.
At C:\Program Files\Lets Encrypt\RDS_INSTALL_CERT.ps1:34 char:1

  • set-RDCertificate -Role RDPublishing `
  •   + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
      + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Set-RDCertificate
    
    

set-RDCertificate : The specified path C:\ProgramData\letsencrypt-win-simple\temp-pfx.pfx is not valid or not
accessible.
At C:\Program Files\Lets Encrypt\RDS_INSTALL_CERT.ps1:40 char:1

  • set-RDCertificate -Role RDWebAccess `
  •   + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
      + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Set-RDCertificate
    
    

set-RDCertificate : The specified path C:\ProgramData\letsencrypt-win-simple\temp-pfx.pfx is not valid or not
accessible.
At C:\Program Files\Lets Encrypt\RDS_INSTALL_CERT.ps1:46 char:1

  • set-RDCertificate -Role RDWebAccess `
  •   + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
      + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Set-RDCertificate
    
    

set-RDCertificate : The specified path C:\ProgramData\letsencrypt-win-simple\temp-pfx.pfx is not valid or not
accessible.
At C:\Program Files\Lets Encrypt\RDS_INSTALL_CERT.ps1:52 char:1

  • set-RDCertificate -Role RDRedirector `
  •   + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
      + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Set-RDCertificate
    
    

set-RDCertificate : Deployment does not contain an RD Gateway server.
At C:\Program Files\Lets Encrypt\RDS_INSTALL_CERT.ps1:58 char:1

  • set-RDCertificate -Role RDGateway `
  •   + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
      + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Set-RDCertificate
    
    

set-RDCertificate : Deployment does not contain an RD Gateway server.
At C:\Program Files\Lets Encrypt\RDS_INSTALL_CERT.ps1:64 char:1

  • set-RDCertificate -Role RDGateway `
  •   + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
      + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Set-RDCertificate
    
    

Remove-Item : Cannot find path 'C:\ProgramData\letsencrypt-win-simple\temp-pfx.pfx' because it does not exist.
At C:\Program Files\Lets Encrypt\RDS_INSTALL_CERT.ps1:70 char:1

  • Remove-Item -Path $tempPfxPath
  •   + CategoryInfo          : ObjectNotFound: (C:\ProgramData\...le\temp-pfx.pfx:String) [Remove-Item], ItemNotFoundEx
     ception
      + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand`
    

@matze1708
Copy link

Hello,

i try this PS Skript.

I make the changes fromNatakugithub,

But i have still this errors

`PS C:\Program Files (x86)\Lets Encrypt> C:\Program Files (x86)\Lets Encrypt\RDS_INSTALL_CERT.ps1
Cmdlet RDS_INSTALL_CERT.ps1 an der Befehlspipelineposition 1
Geben Sie Werte für die folgenden Parameter an:
(Geben Sie zum Aufruf der Hilfe !? ein.)
CertificateImport: C:\ProgramData\win-acme\acme-v02.api.letsencrypt.org\Certificates
RDCB: RDSGATEWAY.Adress.xx
Password: Uj7HJv2kykk6TCDRyqJz2W/+nPJhZYVTd5tMWhzDINI=
Für "op_Subtraction" und die folgende Argumenteanzahl kann keine Überladung gefunden werden: "2".
In C:\Program Files (x86)\Lets Encrypt\RDS_INSTALL_CERT.ps1:23 Zeichen:6

  • if ( ((get-date) - (ls $CertificateImport).LastWriteTime).TotalMinute ...
  •  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : NotSpecified: (:) [], MethodException
    • FullyQualifiedErrorId : MethodCountCouldNotFindBest

Import-PfxCertificate : Die PFX-Datei wurde nicht gefunden.
In C:\Program Files (x86)\Lets Encrypt\RDS_INSTALL_CERT.ps1:32 Zeichen:15

  • ... ewCertPfx = Import-PfxCertificate -FilePath $CertificateImport -Passw ...
  •             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : NotSpecified: (:) [Import-PfxCertificate], FileNotFoundException
    • FullyQualifiedErrorId : System.IO.FileNotFoundException,Microsoft.CertificateServices.Commands.ImportPfxCertificate

Export-PfxCertificate : Das Argument kann nicht an den Parameter "Cert" gebunden werden, da es NULL ist.
In C:\Program Files (x86)\Lets Encrypt\RDS_INSTALL_CERT.ps1:34 Zeichen:29

  • Export-PfxCertificate -cert $newCertPfx -FilePath $tempPfxPath -Force ...
  •                         ~~~~~~~~~~~
    
    • CategoryInfo : InvalidData: (:) [Export-PfxCertificate], ParameterBindingValidationException
    • FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.CertificateServices.Commands.ExportPfxCertificate

Remove-Item : Das Argument kann nicht an den Parameter "Path" gebunden werden, da es NULL ist.
In C:\Program Files (x86)\Lets Encrypt\RDS_INSTALL_CERT.ps1:35 Zeichen:19

  • Remove-Item -Path $newCertPfx.PSPath
  •               ~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidData: (:) [Remove-Item], ParameterBindingValidationException
    • FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.RemoveItemCommand

set-RDCertificate : Der angegebene Pfad "C:\ProgramData\win-acme\temp-pfx.pfx" ist ungültig, oder der Zugriff auf den Pfad ist nicht möglich.
In C:\Program Files (x86)\Lets Encrypt\RDS_INSTALL_CERT.ps1:39 Zeichen:1

  • set-RDCertificate -Role RDPublishing `
  •   + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
      + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Set-RDCertificate
    
    

Get-RDServer : Der RD-Verbindungsbrokerserver ist nicht verfügbar. Stellen Sie sicher, dass Sie eine Verbindung mit dem
RD-Verbindungsbrokerserver herstellen können.
In C:\Windows\system32\WindowsPowerShell\v1.0\Modules\RemoteDesktop\Certificate.psm1:309 Zeichen:22

  • ... webaccess = Get-RDServer -ConnectionBroker $ConnectionBroker -Role @( ...
  •             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
    • FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Get-RDServer

set-RDCertificate : In der Bereitstellung ist kein Server mit Web Access für Remotedesktop vorhanden.
In C:\Program Files (x86)\Lets Encrypt\RDS_INSTALL_CERT.ps1:45 Zeichen:1

  • set-RDCertificate -Role RDWebAccess `
  •   + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
      + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Set-RDCertificate
    
    

Get-RDServer : Der RD-Verbindungsbrokerserver ist nicht verfügbar. Stellen Sie sicher, dass Sie eine Verbindung mit dem
RD-Verbindungsbrokerserver herstellen können.
In C:\Windows\system32\WindowsPowerShell\v1.0\Modules\RemoteDesktop\Certificate.psm1:309 Zeichen:22

  • ... webaccess = Get-RDServer -ConnectionBroker $ConnectionBroker -Role @( ...
  •             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
    • FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Get-RDServer

set-RDCertificate : In der Bereitstellung ist kein Server mit Web Access für Remotedesktop vorhanden.
In C:\Program Files (x86)\Lets Encrypt\RDS_INSTALL_CERT.ps1:51 Zeichen:1

  • set-RDCertificate -Role RDWebAccess `
  •   + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
      + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Set-RDCertificate
    
    

set-RDCertificate : Der angegebene Pfad "C:\ProgramData\win-acme\temp-pfx.pfx" ist ungültig, oder der Zugriff auf den Pfad ist nicht möglich.
In C:\Program Files (x86)\Lets Encrypt\RDS_INSTALL_CERT.ps1:57 Zeichen:1

  • set-RDCertificate -Role RDRedirector `
  •   + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
      + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Set-RDCertificate
    
    

Get-RDServer : Der RD-Verbindungsbrokerserver ist nicht verfügbar. Stellen Sie sicher, dass Sie eine Verbindung mit dem
RD-Verbindungsbrokerserver herstellen können.
In C:\Windows\system32\WindowsPowerShell\v1.0\Modules\RemoteDesktop\Certificate.psm1:299 Zeichen:20

  • ... $gateway = Get-RDServer -ConnectionBroker $ConnectionBroker -Role @( ...
  •             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
    • FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Get-RDServer

set-RDCertificate : In der Bereitstellung ist kein RD-Gatewayserver vorhanden.
In C:\Program Files (x86)\Lets Encrypt\RDS_INSTALL_CERT.ps1:63 Zeichen:1

  • set-RDCertificate -Role RDGateway `
  •   + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
      + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Set-RDCertificate
    
    

Get-RDServer : Der RD-Verbindungsbrokerserver ist nicht verfügbar. Stellen Sie sicher, dass Sie eine Verbindung mit dem
RD-Verbindungsbrokerserver herstellen können.
In C:\Windows\system32\WindowsPowerShell\v1.0\Modules\RemoteDesktop\Certificate.psm1:299 Zeichen:20

  • ... $gateway = Get-RDServer -ConnectionBroker $ConnectionBroker -Role @( ...
  •             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
    • FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Get-RDServer

set-RDCertificate : In der Bereitstellung ist kein RD-Gatewayserver vorhanden.
In C:\Program Files (x86)\Lets Encrypt\RDS_INSTALL_CERT.ps1:69 Zeichen:1

  • set-RDCertificate -Role RDGateway `
  •   + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
      + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Set-RDCertificate
    
    

Remove-Item : Der Pfad "C:\ProgramData\win-acme\temp-pfx.pfx" kann nicht gefunden werden, da er nicht vorhanden ist.
In C:\Program Files (x86)\Lets Encrypt\RDS_INSTALL_CERT.ps1:75 Zeichen:1

  • Remove-Item -Path $tempPfxPath
  •   + CategoryInfo          : ObjectNotFound: (C:\ProgramData\win-acme\temp-pfx.pfx:String) [Remove-Item], ItemNotFoundException
      + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand`
    
    

What can i do?

my external FQDN Points to my Session Broker´s IP.

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