Ryan Bolger

Ryan Bolger

Adventures In Tech

Posh-ACME 3.17.0

Account key import/export and test updates

Ryan Bolger

Just shipped a new Posh-ACME release, version 3.17.0. The highlight of this release is the ability to import or export the private key associated with an ACME account. When creating a new account or performing a key rollover for an existing account, Posh-ACME will normally generate a new random private key automatically. But you now have the option to import an existing key instead of having one generated. It works like this:

# when creating a new account
New-PAAccount -AcceptTOS -KeyFile .\mykey.key

# key rollover on existing account
Set-PAAccount -KeyRollover -KeyFile .\mykey.key

Once the key is imported and associated with the ACME account, you can delete the original file if you want. Keys must be Base64 encoded PEM files and they must adhere to the supported key sizes for the ACME certificate authority you’re using. For Let’s Encrypt, that means RSA keys 2048-4096 in length or EC keys using P-256 or P-384 NIST curves.

There is also a new function called Export-PAAccountKey which allows you to export an existing ACME account key to a PEM file. To export the current account’s key, it works like this:

Export-PAAccountKey -OutputFile .\mykey.key

There are also ID and Force parameters which let you specify a specific account to export and whether or not to overwrite the key file if it already exists. If you have multiple ACME accounts, here’s an example of how you could backup all of those keys.

# define a backup folder and create it if it doesn't exist
$fldr = Join-Path ([Environment]::GetFolderPath('Desktop')) 'AcmeAccountKeys'
New-Item -ItemType Directory -Force -Path $fldr | Out-Null

# list the accounts and export all of the keys
Get-PAAccount -List | %{
    Export-PAAccountKey $_.ID -OutputFile "$fldr\$($_.ID).key" -Force

These new features can also allow you to recover access to a lost ACME account if you still have a copy of the private key. Just try to create a new account using the old account’s key, and the server will return a copy of the old account object. Consider this demonstration:

# Create a new account with a random key and make a note of the 'id' value
# which is generated by the ACME server
New-PAAccount -AcceptTOS -Force

# Export a copy of the account's key
Export-PAAccountKey -OutputFile .\mykey.key

# Remove the local copy of the account
Get-PAAccount | Remove-PAAccount -Force

# Create a new account and specify the account key we previously exported.
# Notice how the account 'id' value is the same as the original account.
New-PAAccount -KeyFile .\mykey.key -AcceptTOS -Force

Keep in mind, this can only recover basic access to the account at the moment. Any orders and certificates associated with the account will still be gone. So if you’re dealing with Posh-ACME backups, it is better to backup the entire config folder.

Updated versions can be found in the PowerShell Gallery or GitHub. Installation instructions are in the Readme.


  • NOTE: Let’s Encrypt is now restricting RSA private key sizes to 2048, 3072, and 4096 for certificates. But Posh-ACME will continue to allow custom key sizes which may still work with other certificate authorities.
  • New-PAAccount and Set-PAAccount -KeyRollover now have a -KeyFile parameter that can be used to import an existing private key instead of generating a new one from scratch.
  • Added Export-PAAccountKey which can be use to export your ACME account private key as a standard Base64 encoded PEM file.
    • For Boulder-based CAs, this can be used to recover lost ACME account configurations if you run New-PAAccount with the -KeyFile parameter and specify the exported key.
  • Updated Zonomi plugin to support alternative providers who use a compatible API. (#282)
  • Fixed a bug in OVH plugin that would prevent TXT record deletion in some cases. (#283)
  • Fixed a bug in many plugins that would prevent TXT record editing when the record name was also the zone root (#280) (Thanks @ShaBangBinBash)
  • Fixed tutorial syntax error (#277) (Thanks @Leon99)
  • Fixed errors in Get-PAAuthorizations when returned object has no ‘expires’ property. (#276) (Thanks @mortenmw)
  • Changed bad nonce retry message from Debug to Verbose so people using PowerShell’s transcript features will see it more easily.
  • A generic platform value has been added to the user agent string the module sends with its ACME requests.
  • Tests have been updated for use with Pester v5. Running them in a dedicated PowerShell process is recommended.

Recent Posts