Using PowerShell to get wildcard certificate from Let’s Encrypt

This is a guide that shows you how to get a publicly trusted wildcard certificate at no cost from Let’s Encrypt using PowerShell.


  • Windows PowerShell 5.1
  • .NET Framework 4.7.2 (link to check)
  • Possibility to add CNAME in DNS

Step by step

Start PowerShell as admin (see information below for non-admin steps)

Verify that PowerShell’s ExecutionPolicy allows running scripts (i.e. RemoteSigned or less)


Otherwise: Set-ExecutionPolicy RemoteSigned


Install-Module -Name Posh-ACME

Accept warnings about untrusted repositories (that is, if you accept PSGallery, a common module repository):



New-PACertificate * -AcceptTOS -Contact <your-email> -DnsPlugin AcmeDns -PluginArgs @{ACMEServer=''} -Install


Explanation of the options used:

* The name you want in the certificate. You can add additional comma-separated names
AcceptTOS Indicates that you accept the Let’s Encrypt Terms of Service (see
Contact Email for expiration notification (optional)
DnsPlugin Which DNS plugin should be used for automatic domain ownership validation. Since my DNS provider Loopia isn’t natively supported by Posh-ACME, I used the ACMEDns option, which requires you to manually add a CNAME record in your DNS provider once, and that can be reused when updating the certificate. Here is a list of DNS providers supported by Posh-ACME:
PluginArgs Options that depends on chosen DNSPlugin
Install This option will install the certificate in the computer’s Certificate Store (requires admin permission, see Getting certificate without admin permission below)

Do not close the PowerShell window!

Add the CNAME record shown in the output of the command you just ran in the DNS registrar for the domain.
Here is an example from Swedish DNS registrar Loopia, but your DNS registrar interface may look different:


Go back to the PowerShell window and press enter to continue.
The script will wait 2 minutes for DNS to propagate:


After that, you should get the certificate:


To see more information about the certificate, you can use the following command:

Get-PACertificate | Format-List


Here you can see basic information about the certificate and that all the relevant files are stored in %LOCALAPPDATA%\Posh-ACME folder, and that it includes a PFX-file if you want to install the certificate on another machine. The default PFX-password is “poshacme”. You can specify your own with the option -PfxPass when running the New-PACertificate command.

Go to the Local Computer certificate store (run certlm.msc) and verify that the certificate has been installed correctly:


clip_image012 clip_image013

Depending on what service you are using the certificate for, you may need to make extra configuration steps in the service to start using the certificate.

You can manually renew the certificate by running the following command:

As you can see, it will not renew certificates that are not about to expire yet (I believe it uses 30 days or less validity time). You can override this by running:

Submit-Renewal -Force

To automate the renewal, you can create a scheduled task that runs this command daily:

Create a file called C:\Cert\AutoRenewal.ps1, containing the command “Submit-Renewal” (not the -Fore option, since you don’t want to renew at every check).

Run the following commands, but first change <password> to your own password
Note: The scheduled task must run in the context of the user requesting the certificate since validation information is stored in that user’s profile.

$Trigger = New-ScheduledTaskTrigger -At 10:00am -Daily
$Action= New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "C:\Cert\AutoRenewal.ps1"
Register-ScheduledTask -TaskName "Certificate AutoRenewal" -Trigger $Trigger -User "$env:USERDOMAIN\$env:USERNAME" -Password '<password>' -Action $Action -RunLevel Highest –Force

Test certificates

For testing, you can switch the Let’s Encrypt server you send your requests to. The test server does not create a publicly trusted certificate but has no rate limiting.

Read more about rate limiting here:

To use test server:


To use production server:

Set-PAServer LE_PROD

It will keep using the specified server until you change it again.

Getting certificate without admin permission

Most steps above work without admin permission, with the exception of installing the certificate in the Computer certificate store.

You might need to restrict the scoop of these commands as well:

Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

Install-Module -Name Posh-ACME -Scope CurrentUser

Then exclude the -Install option in the New-PACertificate command example above.

You will still get a valid publicly trusted certificate, and you can move the created pfx-file to a computer where you want to install it (where you are admin).

Custom Acme-DNS instance

In my example above, I use the public ACME-Dns service. The advantage of that is that your DNS provider does not have to support API access for the Domain Verification part. Instead, you manually create a CNAME record in your DNS provider once that redirects the DNS validation to ACME-Dns.

To increase security, you should use your own instance of Acme-DNS, see here:

Posted in Okategoriserade | 3 Comments

Hyper-V Guests with Windows 10 (1903) hangs when using Enhanced Session/RDP?

Are you also having the issue where accessing your Hyper-V VM Guests works great when connecting via Virtual Machine Connection, but the VM hangs when you try to access it using Enhanced Session or RDP?

The VM becomes irresponsible and the only solution is to use Turn off (shutdown doesn’t work). The machine starts to continuously consume about 12% or 24% CPU (seems to depend on the number of CPU cores).

I run client Hyper-V on a Windows 10 (1903) machine, and the guest is also Windows 10. Enhanced Session used to work great, until Windows 10 (1903).

After some troubleshooting and researching I found out that a new RDP display driver called WDDM was introduced in 1903. By disabling WDDM and reverting to the old XDDM driver the problem went away for me.

Here’s how to do it:

Start the Local Group Policy Editor:


Navigate here:
Local Computer Policy
/Computer Configuration
  /Administrative Templates
   /Windows Components
    /Remote Desktop Services
     /Remote Desktop Session Host
      /Remote Session Environment

Configure the setting Use WDDM graphics display driver for Remote Desktop Connections to Disabled:


In an AD environment you can of course use the regular Group Policy Management.

You can also create and import a reg-file with the following text:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services]

Reboot the Guest VM.

Yay, now I can access that guest VM using Enhanced Session again.

Posted in Hyper-V, RDP, Windows 10 | Tagged , , | 2 Comments

Enable FIDO2 credential manager in Windows 10

Once you have enrolled your FIDO2 security key in Azure AD (which can be done here), you can easily sign-in to web pages that use Azure AD as Identity Provider without needing to enter your password.

If your security key doesn’t have a fingerprint reader, you need to enter the key’s PIN but remember that this is only to unlock the secret on the key, and it is never sent or stored anywhere outside of the key:

If you also want to sign-in on a Windows 10 machine with a FIDO2 device (currently supported on Azure AD joined and version 1809 or higher), you need to enable the FIDO security key credential provider on that machine first:

This can be enabled in one of three ways:

1. Using Intune, as explained here.

2. If Intune doesn’t manage the client, you can manually create a provisioning package using Windows Configuration Designer  (an application that is available in the Microsoft Store. The steps are explained here.
Note that you have to choose All Windows desktop editions, if you choose All Windows editions, the setting isn’t available.

3. You can enable the FIDO credential provider, you by adding the following Registry Setting:

Windows Registry Editor Version 5.00

Copy the text above to a new text file, call it something.reg, double-click it and accept the warning.

Note! I haven’t seen the last method mentioned anywhere official, so it might not be supported. Use it with caution and test before using it in production.

Posted in fido2, Password, passwordless | Tagged , , | Leave a comment

Always get the English version at

When you visit, it shows pages in the local language you have configured in your browser’s settings. Sometimes the pages are properly translated by humans, sometimes it is machine translated.

I always want the English versions of the Docs site pages, but I do not want to have English as the default language in my browser since I want Swedish version on other websites.

I discovered the Firefox plugin called Redirector. It does one very simple task. It looks for pattern matches in the URL and modifies them according to my rules.

So I installed it and created the following Redirect rule:


The * is a wildcard, so anything will match. $1 is the value that the first wildcard represented. Note that my rule only matches Swedish (sv-se), you may need to modify your rules to match your language (or all languages).

Now, whenever I visit a page that starts with* it is immediately changed to*:


There are similar extensions for Chrome, but I have not tested them yet:


Switcheroo Redirector

Posted in Okategoriserade | Leave a comment

Azure Information Protection – Indication that a label encrypts

I’ve been missing an easy way to tell if an AIP label will encrypt information, or if it “only” adds the label metadata and/or visual markings. Sure, I can explain it in the description of the label, but that is not very intuitive.

We cannot add images to AIP labels, but I realized that there are a lot of symbols in the Unicode world – that are in fact just text but shown as icons – and I found this padlock icon using Word’s Insert Symbol feature:


If I insert that symbol into Word, I can then copy it from there and paste it wherever I want it.

This is what it looks like as text in Word 2016:


This is what it looks like in the Azure Portal, after I have pasted it into the Label display name and Description of an AIP label:


This is what it looks like in Word 2016 as an AIP label:


So the symbol looks different on different platforms, but it is always a padlock. There are other fonts that have padlocks, but I chose Segoe UI Symbol, since that font is installed by default in Windows.

Please note that using an unusual Unicode character might cause issues:

PowerShell ISE can partly handle the symbol correctly:


while PowerShell cannot:


Azure Information Protection Client can show it (right-clicking on files in Windows):


Cloud App Security can also show it correctly:


I do not know how it will look on platforms that do not have that font.

I do not know if other systems (like DLP) are able to correctly read/set the label. Many DLP can however use partial matching of strings.

Please leave a comment below if you have any more info on where this works or does not work.

Posted in AIP, CAS, encryption, information protection, Rights Management Services, RMS | Leave a comment

Use PowerShell to see if you are mitigating Meltdown and Spectre

Microsoft has released a PowerShell module on PSGallery that can test if you are mitigating the issues that Meltdown and Spectre are using.

Simply run the following command in an elevated PowerShell window:

Install-Module SpeculationControl

Then use the following command to verify mitigations:


This was the result om my laptop (Lenovo X1 Yoga) before patching it:


Then I installed this patch (via regular Windows Update):

Update history

After installing the patch and rebooting, it looked much better:

SpeculationControl-X1_efter update

Note that some of my older hardware only managed to mitigate some of them, and some mitigations are sometimes not turned on by default, due to some dependencies.

Posted in Meltdown, PowerShell, Spectre, Updates | Tagged , , , | Leave a comment

Get a free publicly trusted certificate using Let’s Encrypt, PowerShell and DNS

I have previously blogged about the free publicly trusted certificate solution Let’s Encrypt, see here.

In this post, I will show how you can request a certificate with a PowerShell script and prove ownership of the domain name using DNS validation. It is perhaps more common and faster to validate ownership of domain names by publishing a challenge response via HTTP (since it can be validated immediately), but sometimes you want to request a certificate for a domain name that does not host a webserver, such as email and RDP servers.

I am using the PowerShell module ACMESharp, which is an implementation of ACME, the protocol that Let’s Encrypt is using for validation and requests.

For more information about Let’s Encrypt, take a look at their FAQ.


  • Totally free
  • Simple with few steps
  • Publicly trusted certificate
  • Since we export a PFX (including the private key), the request can be performed on any computer (not necessarily from the server that will use the certificate).


  • Requires you to manually add DNS records.
  • Waiting for the new DNS record to show up can take some time (due to DNS caching).
  • The certificate is only valid for 3 months. There is no support for renewal in the PowerShell implementation yet, but on the other hand, it is quick, easy and free to request a new certificate for the same domain name again.


  • I take no responsibility for what this script does, test before running in production.
  • I am not a coder, so this PowerShell-script probably breaks all of the practice rules.
  • The script automatically downloads and installs nuGet (which is then used to download the PowerShell module ACMESharp) using PackageManager. PackageManager is included in PowerShell v5 but has to manually be installed as an addon if you run PowerShell v3 and v4. Find you PowerShell version running $PSVersionTable and look at the value PSVersion.
    PackageManager for PowerShell v3 and v4 can be downloaded here:


Note: The video below shows these steps.

  1. Run the PowerShell script in an elevated PowerShell console.
  2. Supply the following parameters
    1. ExpirationEmail
      1. This email will receive an email notification when the certificate is about to expire. I have never received any other email, but you can enter a bogus email address.
    2. PFXPassword
      1. The PFX file will be protected by this.
    3. SANList
      1. A comma-separated list of domains you want in the certificate. You can add as many as you want, but you will need to add a DNS record for each of them (for domain name ownership verification). Note that wildcards are not allowed right now, but that has been announced to become available in 2018.
  3. Answer any questions the script asks.
  4. Done! The PFX will be created in the same folder as the script.
    The PFX will have the domain names as the file name.
  5. If you need more than the PFX, look in the following folder:
    There you will find the certificate request, the certificate in PEM/KEY format, Issuing CA certificates etc.


This is what a certificate will look like:



Here is a 4 minute video where I run the script, so you can see how it looks:

Note that I do not show adding the DNS records to the public DNS in the video since it differs depending on your DNS provider. For me it looks like this:


The script

Here is a link to the latest version of the script:

Bitly started charging $350/year for custom domains in shortlinks. Here it the full URL that the link pointed to:!AGxuu7wuvZ4Utmw&cid=6BAD75A56D4DD590&id=6BAD75A56D4DD590!881465&parId=6BAD75A56D4DD590!862272&o=OneUp

Any feedback and improvement suggestions are highly welcome.

Thanks for reading!

Posted in CA, Certificates, LetsEncrypt, PKI, SAN, SSL | Tagged , , , , , | Leave a comment

Force update of Advanced Threat Analytics (ATA) on Windows Server 2016

When there is an update available for ATA you will get a blue arrow notification in the portal. Hovering with the mouse pointer over the icon will show what’s new in the available update:


The update notification tells you to go to Windows Update on the machine running the ATA Center. But when you check for updates, there are none available:


What is going on here?

It is because ATA updates are technically not classified as Recommended updates. There are a lot of extra hoops and requirements to get this classification (since everyone will get them). Using Optional is more flexible.

On Windows Server 2016 there is no obvious way to look for Optional updates, like there is on Windows Server 2012 R2 and earlier:


But you can use a tool that normally is used to configure Core installations called sconfig.

On the ATA Center, running on Windows Server 2016, run sconfig:


Select option 6 (Download and Install Updates):


You will be asked if you want to search for All or Recommended updates only:


Note that if you chose Recommended here, you will get the same result as in the normal settings interface:


If you instead chose All updates, you will find the ATA update (and any other Optional Updates):


I do not want to install Silverlight, so I chose to Select a single update and chose the number of the ATA update:


After a while, the installation wizard of the ATA update will start:


After you finish the installation you will see the installation result:


When you now go to the ATA Portal you will see that the update notification is gone:


The ATA gateways might be automatically updated now, depending on how you have configured updates in ATA:


You will have health alerts as long as the gateways are not updated:


I hope this blog post helped someone.

Posted in ATA, Updates | Tagged , , , | 1 Comment

Certificate related problems when using a web proxy server

I have several times encountered these issues, so it decided it was time to write a blog post about it.

The situation

You are using a proxy server for web communication. Direct communication to the Internet is blocked. The proxy is configured in Internet Explorer Options, as shown in these screenshots:



If you do not configure this, you cannot reach the Internet.
If you do configure this, you can reach the internet.
Just as expected.

The issue

Even if the proxy is configured correctly, as seen above, some Internet communication is still blocked.

One common problem area is certificate validation, specifically downloading CRLs from the Internet. I have seen problems when starting CA servers (after Root CA CRL renewal) and/or when or accessing NDES web pages. See examples at the end of this post for details. If you solve something else, let me know so I can add it to help others.

The reason

There are actually two different proxy settings in Windows, WinINet and WinHTTP.

This is what we configure in the screenshots above. Most applications use this setting.

This is a separate proxy setting. Most Windows services use this setting, including the one responsible for certificate revocation checking. This proxy setting has no GUI but can be configured using the command netsh.

You can read more about the differences between WinINet and WinHTTP here.
Especially note Services Support (Can be run from a service or a service account [Yes/No]).

The solution

The solution is to configure WinHTTP with the same proxy settings as WinINet.

This command shows the current WinHTTP proxy configuration:

netsh winhttp show proxy


As you can see, no proxy server is configured for WinHTTP.

You can manually add the proxy configuration (and optional Bypass List) by entering the relevant proxy information:

set proxy bypass-list=”*”

But there is an easier way. You can simply copy and apply the current WinINet proxy configuration to WinHTTP:

netsh winhttp import proxy source=ie


Note that this requires an elevated prompt, otherwise you will get the error message “Error writing proxy settings. (5) Access is denied.”

This has solved many communication issues I have had where a web proxy server is used.

If you wish to reset the WinHTTP proxy setting back to the no proxy setting you can use the following command:

netsh winhttp reset proxy


Example errors that were solved

Starting Active Directory Certificate Services

When trying to start the CA server you get this error message:

The revocation function was unable to check revocation because the revocation server was offline. 0x80092013 (-2146885613 CRYPT_E_REVOCATION_OFFLINE)

The event log shows Event Id 100 from source CertificationAuthority:

Active Directory Certificate Services did not start: Could not load or verify the current CA certificate <CA name>. The revocation function was unable to check revocation because the revocation server was offline. 0x80092013 (-2146885613 CRYPT_E_REVOCATION_OFFLINE).

Also, Event Id 48 from source CertificationAuthority:

Revocation status for a certificate in the chain for CA certificate 0 for <CA Name> could not be verified because a server is currently unavailable.  The revocation function was unable to check revocation because the revocation server was offline. 0x80092013 (-2146885613 CRYPT_E_REVOCATION_OFFLINE).

Note: A dirty trick to quickly get the CA up and running is to disable CRL checking on the CA server:

certutil –setreg ca\CRLFlags +CRLF_REVCHECK_IGNORE_OFFLINE

This is of course not recommended and must be turned back on as soon as the CRL is available again, but might be justified in some rare cases.

Accessing NDES / SCEP web pages

Visiting https://FQDN works great (shows IIS standard home page).

But when trying to access the URL https://FQDN/certsrv/mscep/mscep.dll you get this error message:

500 – Internal server error.
There is a problem with the resource you are looking for, and it cannot be displayed.

The same message appears when going to the URL http://<FQDN>/certsrv/mscep_admin

The Application event log on the NDES server shows the following error:

Event ID 10: The Network Device Enrollment Service cannot retrieve one of its required certificates (0x80070057). The parameter is incorrect.

followed by:

Event ID 2: The Network Device Enrollment Service cannot be started (0x80070057).  The parameter is incorrect.

These two error events occur every time I revisit the URLs.

Have you solve an issue

If you run into any issues solved by this, please let me know so I can add them here to help others.

Posted in CA, Certificates, CRL, NDES, PKI, SCEP | Tagged , , , | 4 Comments

Information protection with EMS [video]

Here’s a new short video from Microsoft that shows how you can protect your organisation’s information, using solutions that are part of the Enterprise Mobility + Security suite, such as Cloud App Security, Intune and Azure Information Protection.

Posted in AIP, CAS, EMS, Rights Management Services, RMS | Tagged , , , , | Leave a comment