Comments (15)
Hey @fthobe, thanks for the suggestion. However, this functionality already exists in the Set-RDSHCertificate
function except under the hood it uses the native Get-CimInstance
/Set-CimInstance
functions instead of shell'ing out to the wmic
utility (which is now deprecated)
from posh-acme.deploy.
I lower my head in a humble manor and request a change in documentation:
Change "Remote Desktop Session Host" to "Remote Desktop Session Host / Remote Desktop Listener" :D
from posh-acme.deploy.
Stupid question, you just answered
Just out of curiosity, what would be the appropriate current way to request thumbprints then?
from posh-acme.deploy.
It's not your fault you didn't realize. Microsoft has been confusing people with the naming in this tech since they renamed from Terminal Services and then split out the functionality between the old remote administration mode which can be used out of the box with no extra roles or licensing installed and the full fledged Remote Desktop Services role which has a whole wizard based cert management workflow if I recall correctly.
You can tell they're even internally confused because in that same documentation site, there's another entirely different page explaining how to configure the same cert and they don't mention "Remote Desktop Listener" even once.
https://learn.microsoft.com/en-us/troubleshoot/windows-server/remote/custom-server-authentication-certificate-for-tls
There's also no "Listener" mentioned on the page describing the services associated with the Remote Desktop Services role here. https://learn.microsoft.com/en-us/windows-server/remote/remote-desktop-services/rds-roles
from posh-acme.deploy.
@rmbolger so how does renewal behave? I just install posh-acme and posh-acme.deploy and follow the procedure described in https://www.dvolve.net/blog/2019/12/using-lets-encrypt-for-active-directory-domain-controller-certificates/ with my custom flavor of FQDN identification and add RDP session host and all should work renewal included given that I schedule the task?
from posh-acme.deploy.
More or less, yes.
You would generally run Set-RDSHCertificate
with either the output of Submit-Renewal
or an explicit call to Get-PACertificate
. So if we modify the renewal script example, I'd probably go with something like this:
if ($newCert = Submit-Renewal -Verbose) {
$newCert | Set-RDSHCertificate
$oldCert | Remove-Item
Restart-Service ADWS
}
So instead of just calling Submit-Renewal
and ignoring the cert object output, we save it to a variable and then use that with the Set-RDSHCertificate
function before deleting the old cert.
Alternatively, this is effectively the same code.
if (Submit-Renewal -Verbose) {
Get-PACertificate | Set-RDSHCertificate
$oldCert | Remove-Item
Restart-Service ADWS
}
from posh-acme.deploy.
So technically the first script creates the cert, stores into personal and sets for RDP and the second renews it, correct?
# Cloud Flare requires a simple API token, securing the string to keep it safe
$token = ConvertTo-SecureString '[INSERT API KEY]' -AsPlainText -Force
$pArgs = @{CFToken=$token}
# The default certificate password is "poshacme", but we prefer some extra security. At this point you could also just use the CF token.
$CertPass = '$token'
# To get the correct hostname independent of features installed, use System.Net.Dns (does not work on linux).
$certName = @([System.Net.Dns]::GetHostEntry([string]"localhost").HostName)
# This notification email is contacted if the certificate is close to expiration date.
$notifyEmail = '[[email protected]]'
# Constructs all Cert Params for a successful request.
$certParams = @{
Domain = $certName
PfxPass = $CertPass
DnsPlugin = 'Cloudflare'
PluginArgs = $pArgs
AcceptTOS = $true
Install = $true
Contact = $notifyEmail # optional
Verbose = $true # optional
}
New-PACertificate @certParams
# Sets the certificate also for RDP Host Listener
Set-PAOrder $certName
Get-PACertificate $certName | Set-RDSHCertificate -Verbose
Start-Transcript $env:LOCALAPPDATA\cert-renewal.log -Append
$hostname = @([System.Net.Dns]::GetHostEntry([string]"localhost").HostName)
$oldCert = Get-ChildItem Cert:\LocalMachine\My |
Where-Object { $_.Subject -eq "CN=$hostname" } |
Sort-Object -Descending NotAfter |
Select-Object -First 1
if (Submit-Renewal -Verbose) {
Get-PACertificate | Set-RDSHCertificate
$oldCert | Remove-Item
Restart-Service ADWS
}
Stop-Transcript
from posh-acme.deploy.
When adding additional services do I just invoke the whole line substituting "Set-RDSHCertificate" or just add another "| Set-Someotherservice" at the end of the line?
Get-PACertificate | Set-RDSHCertificate
from posh-acme.deploy.
Those functions don't have a passthru option that would send the original object back out to the pipeline (though that's an interesting idea). So you'd need another complete line.
from posh-acme.deploy.
Those functions don't have a passthru option that would send the original object back out to the pipeline (though that's an interesting idea). So you'd need another complete line.
So the script above looks fine but I need multiple get PA to add services, correct?
from posh-acme.deploy.
Yes. Or you could use the model where you assign the output of Submit-Renewal
to a variable and use that variable instead of Get-PACertificate
.
from posh-acme.deploy.
Yes. Or you could use the model where you assign the output of
Submit-Renewal
to a variable and use that variable instead ofGet-PACertificate
.
You make it sound so easily while I have no idea whatsoever how that would look like 😅
from posh-acme.deploy.
In my comment before you posted your script, it's the first example code block.
from posh-acme.deploy.
Hey @rmbolger Sorry for always dragging issues for months but I switched company and the amount of work I found was staggering.
I think I nailed it now, but when I manually run the task from the schedule to check the log, nothing happens.
Script A contains the minified ps script while script b contains the written out version.
Some additional questions from somebody who's not very experienced in PS:
- In the minified version you changed
Where-Object
to?
, does that always work? what are conditions? - Idem with "Sort-Object -Descending" > "sort -d", "Remove-Item" > "ri"
- Are you using any handy tool to minify?
Thanks, you helped me a lot and I really appreciate it. I am going to publish a couple of scripts I wrote to publish LE certs across various systems over the next weeks and you were a big help on all of this.
Script A: Initial Request and Scheduling of renewal
# run in .\PsExec64.exe -i -h -s powershell.exe
# Install Posh-Acme and Posh-Acme Deploy with all dependencies
Install-Module -Name Posh-ACME -Scope AllUsers -Force -SkipPublisherCheck
Install-Module -Name Posh-ACME.Deploy -Scope AllUsers -Force -SkipPublisherCheck
# Cloud Flare requires a simple API token, securing the string to keep it safe
$token = ConvertTo-SecureString 'token' -AsPlainText -Force
$pArgs = @{CFToken=$token}
# The default certificate password is "poshacme", but we prefer some extra security. At this point you could also just use the CF token.
$CertPass = '$token'
# To get the correct hostname independent of features installed, use System.Net.Dns (does not work on linux).
$certName = ([System.Net.Dns]::GetHostEntry([string]"localhost").HostName)
# This notification email is contacted if the certificate is close to expiration date.
$notifyEmail = '[email protected]'
# Constructs all Cert Params for a successful request.
$certParams = @{
Domain = $certName
PfxPass = $CertPass
DnsPlugin = 'Cloudflare'
PluginArgs = $pArgs
AcceptTOS = $true
Install = $true
Contact = $notifyEmail # optional
Verbose = $true # optional
}
New-PACertificate @certParams
# Sets the certificate also for RDP Host Listener
Set-PAOrder $certName
Get-PACertificate $certName | Set-RDSHCertificate -Verbose
# Sets the scheduler to check and renew certificate when due
$taskname = "Renew SSL Server Certificate"
$taskdesc = "Renews the Let's Encrypt certificate installed on this server."
$actionArg = '-C "Start-Transcript $env:LOCALAPPDATA\cert-renewal.log -Append; $name=([System.Net.Dns]::GetHostEntry([string]"localhost").HostName); $oldCert=gci Cert:\LocalMachine\My | ?{ $_.Subject -eq \"CN=$name\" } | sort -d NotAfter | select -f 1; if (Submit-Renewal -Verbose) { Get-PACertificate | Set-RDSHCertificate; $oldCert | ri; Restart-Service ADWS } Stop-Transcript; exit $LASTEXITCODE"'
$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument $actionArg
$trigger = New-ScheduledTaskTrigger -Daily -At 2am -RandomDelay (New-TimeSpan -Minutes 30)
$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Minutes 30)
Register-ScheduledTask $taskname -Action $action -Trigger $trigger -User 'System' -Settings $settings -Desc $taskdesc
Script B Renewal written out without Task Scheduler
Start-Transcript $env:LOCALAPPDATA\cert-renewal.log -Append $name=([System.Net.Dns]::GetHostEntry([string]"localhost").HostName)
$oldCert=gci Cert:\LocalMachine\My |
Where-Object { $_.Subject -eq \"CN=$name\" } |
Sort-Object -Descending NotAfter |
Select-Object -First 1
if (Submit-Renewal -Verbose) {
Get-PACertificate | Set-RDSHCertificate
$oldCert | ri; Restart-Service ADWS
}
Stop-Transcript
from posh-acme.deploy.
Hey @rmbolger
I also struggle a little with a nonce error, Am I understanding correctly that posh-acme.deploy just falls back to generating a new one?
**********************
Windows PowerShell transcript start
Start time: 20240808004658
Username: GMSERVICE\SYSTEM
RunAs User: GMSERVICE\SYSTEM
Configuration Name:
Machine: MI-DEV-PS (Microsoft Windows NT 10.0.20348.0)
Host Application: powershell.exe
Process ID: 5540
PSVersion: 5.1.20348.2582
PSEdition: Desktop
PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.20348.2582
BuildVersion: 10.0.20348.2582
CLRVersion: 4.0.30319.42000
WSManStackVersion: 3.0
PSRemotingProtocolVersion: 2.3
SerializationVersion: 1.1.0.1
**********************
Transcript started, output file is C:\Windows\system32\config\systemprofile\AppData\Local\cert-renewal.log
PS>TerminatingError(Invoke-WebRequest): "{
"type": "urn:ietf:params:acme:error:badNonce",
"detail": "JWS has an invalid anti-replay nonce: \"Cb9-D9qJCtold24rWJytkwMfpT0aSbw-ohnEayo0PLMQaW-w_bk\"",
"status": 400
}"
VERBOSE: Nonce rejected by ACME server. Retrying with updated nonce.
VERBOSE: Checking for updated renewal window via ARI
WARNING: Order 'mi-dev-ps.gmservice.app' is not recommended for renewal yet. Use -Force to override.
**********************
Windows PowerShell transcript end
End time: 20240808004659
**********************
from posh-acme.deploy.
Related Issues (20)
- WSMAN RDP HOT 5
- Consider task creation HOT 2
- Dev install module path HOT 6
- Set-IISCertificate doesn't work with Site names that have some uncommon characters. HOT 2
- IIS Binding Help HOT 3
- New-ItemProperty and Set-IISCertificate remote script issue HOT 8
- RDS Certificate needs NETWORK SERVICE permissions HOT 10
- Allow install cert by pfx file only HOT 6
- Trying to fix "The WebAdministration module is required to use this function" on Server 2016 HOT 3
- Need some help on creating a renewal script that renews wildcard certificates bound to multiple websites HOT 6
- Executing remote commands using Invoke-Command or Enter-PSSession produces errors HOT 1
- Guide for Exchange HOT 4
- Support for newer Powershell core versions HOT 9
- Set-IISCertificate issue with multiple sites, Server Name Identification (SNI) HOT 4
- Enhancement to Set-IISCertificateNew to handle multiple bindings in a single call HOT 5
- Allow for multiple policies and/or wildcards with Set-NPSCertificate HOT 7
- Installing cert on IIS -> getting error: A specified logon session does not exist. It may already have been terminated HOT 7
- Dependency issue HOT 1
- Set-IISCertificate - RequireSNI Switch Refactor HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from posh-acme.deploy.