ZeroSSL DNS verification for auto renewal


Hello. Not sure if this is a good place to ask for help or not. Hopefully it is.

I am using ZeroSSL installed on a Win2016 server to get a wildcard certificate. The cert is being used for some RDS stuff. I’ve got things working and know how to generate the cert and load it where necessary using powershell. My issue now is automating the renewal process. Wildcard certs requires a client that support API 2 (like ZeroSSL) and has to be done through DNS. That DNS verification process is where I’m having trouble. I believe on Linux there are some clients that have things built already to automate the process as long as your DNS provider has an API for updating records. But from what I can tell ZeroSSL doesn’t have anything like that.

My DNS provider is CloudFlare which from what I can see has an API for deleting/adding/editing DNS records using your email and API Key. I’ve also found a decent amount of info on doing this from a Windows Server using powershell.

So if the ZeroSSL client doesn’t provide the necessary hooks into CloudFlare I’m thinking it would be possible to output the DNS challenge TXT record from ZeroSSL and “feed” it to a different powershell script. The ZeroSSL client would have to stay open and wait a bit for the TXT record to get added and then finish checking and return an appropriate response that it completed correctly.

Does anyone know if what I want to do is possible or already exists (for wildcards & DNS verification)? Anyone have any insight on how to get the ZeroSSL client to “output” the DNS TXT record so it can be used by a different script? The ZeroSSL docs feel a bit…sparse…when it comes to stuff like this.



Is there a way you can make run on your machine? Because it natively supports Cloudflare DNS validation.


I doubt it, at least not in any recommendable way - the server in question is running Windows.

I do, however, believe that it may be worth exploring alternative Windows client options that may have better support, and more documentation, for this use-case.


I’m going to look at Posh-Acme. It seems like it supports wildcard certs and has a bunch of providers (Cloudflare included). Have to run some Windows updates first (old test server).


Hey @jayg30, I’m the author of Posh-ACME. Let me know if you have any trouble (preferably via GitHub issue). Wildcard certs and CloudFlare are both supported. The main hassle people usually have getting Posh-ACME running on Windows is having .NET 4.7.1 or later installed.

I’ve also been working on a sister module that makes it easier to actually deploy the certs you get with Posh-ACME. There’s no official release yet, but the current dev version on GitHub is usable and in particular has a function for deploying to RD Gateway and RD Session Host.


Thanks. I’m up and running and it works very well.

For RDS there are a few roles you probably want certs set for;

Set-RDCertificate -Role RDPublishing
Set-RDCertificate -Role RDWebAccess
Set-RDCertificate -Role RDRedirector
Set-RDCertificate -Role RDGateway

I was originally going to just run these in a powershell script after a renewal (Submit-Renewal in this case).

One thing I’m noticing though is that Submit-Renewal doesn’t seem to return any result code. My initial thought was to determine if I needed to set the RD certificates depending on what was returned from the renewal attempt.

I guess the other approach would be to inspect the thumbprint of the certificate currently set vs what is at the %localappdata%\Posh-ACME folder path?

Or just set it every time regardless. Which probably doesn’t matter but is a waste of time.


It would only return something to the pipeline if a cert is actually renewed. So if the suggested renewal date hasn’t been reached yet, it will just exit with no output other than a warning about not having reached the renewal window. You can use -Force to ignore the suggested renewal window.

What it would normally return is what you get back from Get-PACertificate which is useful to test deployment scripts with. Use Get-PACertificate | fl to show all of the output properties. Ultimately, Submit-Renewal is just calling New-PACertificate which returns the output of Get-PACertificate when it’s done.


I was performing a test on a script and used -Force for renewal, which worked. However I didn’t see a TXT record show up in my cloudflare DNS. Shouldn’t that happen every time to prove ownership of the domain before providing a new certificate? Or is there some “grace period” allowed between DNS validations?


There is indeed a grace period where previous validations are still good and don’t need to be re-checked. I don’t recall what it is exactly, but I’m pretty sure it’s in the realm of 20-30 days. So when you create a new order (which is really all a renewal is) for a cert that contains only names that are still in the grace period, the ACME server essentially skips the “pending” order status and goes straight to “ready” which tells the client to go ahead and download the signed cert without needing to address any challenge validations.

If you want to force a new challenge, you need to add a new name that hasn’t been validated yet. Alternatively, I think you might also be able to do it by creating a new ACME account (New-PAAccount) and requesting the original cert from that one instead.


This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.