Automating Certificate Renewal With Let’s Encrypt and PowerShell
TLS certificates protect web applications, APIs, reverse proxies, and internal services from interception and impersonation. Let’s Encrypt makes publicly trusted certificates available without licensing fees, but its 90-day validity period means renewal must be treated as an operational process rather than an occasional manual task.
PowerShell provides a practical way to automate certificate requests, validation, installation, and service reloads across Windows servers. With the Posh-ACME module, a scheduled task, and useful logging, Australian infrastructure teams can maintain HTTPS reliably across IIS, load balancers, hybrid workloads, and home lab environments.
Choosing The Right ACME Validation Method
Let’s Encrypt uses the ACME protocol to verify control of a domain before issuing a certificate. HTTP-01 places a temporary file under /.well-known/acme-challenge/, making it suitable for a public IIS website with port 80 routed to the correct server. DNS-01 creates a TXT record and is better for wildcard certificates, private services, or environments where inbound HTTP traffic is restricted.
DNS-01 is often the stronger option for Australian organisations using split-horizon DNS, Azure, AWS, or a local provider. The DNS API must be protected carefully because anyone holding the API credential may be able to prove control of the domain. Use a narrowly scoped token, store it outside source control, and audit changes through the provider’s logging system.
Installing Posh-ACME On Windows
Install Posh-ACME from the PowerShell Gallery on the server responsible for certificate management. Running PowerShell as an administrator is useful when the certificate will be placed in the local machine store or assigned to an IIS binding. A typical setup begins with Install-Module Posh-ACME -Scope AllUsers, followed by Import-Module Posh-ACME.
Create an ACME account and select the production directory only after testing with Let’s Encrypt’s staging endpoint. Staging avoids rate-limit problems while scripts are being developed. A request can then be created with a command such as New-PACertificate -Domain 'www.example.com' -AcceptTOS -Contact 'admin@example.com', with the validation plugin and DNS credentials supplied according to the chosen method.
Protecting Keys And Certificate Files
The private key is more sensitive than the public certificate and should never be emailed, committed to Git, or copied into a shared administrative folder. Use an encrypted secrets store, Windows Credential Manager, a managed password vault, or a cloud secret service. File-system permissions should allow access only to the renewal account and the service that needs the key.
When a PFX file is required, protect it with a strong password and import it into Cert:\LocalMachine\My. The certificate thumbprint should be captured after import, then used to update the relevant IIS HTTPS binding. For services running under a group managed service account, verify that the account can read the private key through the certificate’s private-key permissions.
Building A Safe Renewal Script
A renewal script should check the certificate’s remaining validity before requesting a replacement. Renewing when fewer than 30 days remain provides enough time to investigate DNS, firewall, or ACME account failures without causing an outage. The script should also confirm that the issued certificate contains the expected subject alternative names.
After importing the new certificate, update the service binding and perform a controlled reload. IIS commonly detects certificate binding changes without a full reboot, while applications behind HAProxy, NGINX, or a Radware appliance may require a configuration reload. Write each operation to the Windows event log or a central log platform, including the domain, thumbprint, exit status, and renewal timestamp.
Scheduling And Monitoring The Job
A Windows Scheduled Task is sufficient for many environments. Run it daily under a dedicated service identity, use the highest privileges required for certificate-store access, and set the trigger for a quiet period in the relevant time zone. Australian organisations with servers in Sydney or Melbourne should account for Australian Eastern Standard Time and daylight saving when reviewing logs or planning maintenance windows.
The task should return a non-zero exit code when validation, import, or binding changes fail. Send alerts through an existing monitoring platform rather than relying solely on email from the script. Track certificate expiry independently from the renewal job so a disabled task, broken DNS API token, or failed service reload is detected before customers see browser warnings.
Operating Certificates Across Hybrid Environments
Certificate automation becomes more complex when an application moves between an on-premises cluster, AWS, and a colocation facility. Keep issuance close to the system that terminates TLS, or distribute the renewed certificate through a controlled pipeline. A migration involving EC2, load balancers, and Windows workloads may benefit from this AWS migration guide, particularly when certificate locations change during cutover.
Australian businesses should also map certificate handling to their compliance obligations. The Privacy Act 1988 and the Australian Privacy Principles make protection of personal information important, while regulated organisations may need controls aligned with APRA CPS 234 or the Australian Government Information Security Manual. Certificates do not provide compliance by themselves, but automated renewal, restricted key access, reliable monitoring, and documented recovery procedures support a defensible security process.
Testing Failure Recovery Before Production
A renewal workflow is incomplete until it has been tested against common failures. Temporarily block outbound ACME traffic, provide an invalid DNS credential, remove permission to the certificate store, and simulate an unavailable web service. The script should leave the currently working certificate in place when a new certificate cannot be validated or installed.
Use a staging account and a non-production hostname to test the complete lifecycle, including certificate replacement and application reload. Check the result from outside the network because internal DNS may hide routing errors. This is particularly important for services accessed over NBN connections, mobile networks, or public cloud paths where external DNS and firewall behaviour can differ from an office test.
Retain renewal logs, task configuration, ACME account details, and recovery steps in the organisation’s operational documentation. With those controls in place, PowerShell turns Let’s Encrypt renewal from a recurring manual interruption into a predictable part of Windows infrastructure management.