Windows Server Hardening with PowerShell DSC

Operating system hardening is the process of improving the security of a default OS installation to minimize the attack surface that can be exploited by an attacker. But doing this manually on each system that is deployed on-premise or in the cloud is a cumbersome task. It can lead to inconsistent security configurations because of human error or due to configuration drift over time.

A solution for more efficient OS hardening is using configuration management tools such as Ansible, Puppet or PowerShell Desired State Configuration (DSC). These tools allow you to consistently (re)apply a secure configuration state across a large number of systems. We have chosen to use PowerShell DSC, an addition to the PowerShell scripting engine, because it is natively supported by all Windows versions and can be applied on-premise or in the cloud by Azure Automation.

One of our NVISO interns, Patrick Randriambololona, has created PowerShell DSC code to automate several hardening guidelines. We have made this code publicly available on our NVISO GitHub in the posh-dsc-windowsserver-hardening repository so you can start using it in your own environment:

In Windows, a large number of improvements can be made to secure its default configuration. We have automated 3 different hardening baselines based on industry standards and best practices.

CIS Microsoft Windows Server 2016 benchmark v1.1.0

The Center for Internet Security (CIS) is a nonprofit organization that creates best practice security recommendations for a wide range of IT systems. Using a crowdsourcing model, it has defined a secure configuration benchmark for Windows Server 2016 which have become an industry standard.

The CIS benchmark can be found on their site:

It contains over 300 security controls and the PowerShell DSC code for configuring them can be found in the file CIS1.1.0_WindowsServer2016.ps1.

Before applying the CIS benchmark in your production environment, each security control should be carefully evaluated and tested since it can have impact on the applications running on your systems.

Azure Security Center Baseline for Windows Server 2016

Microsoft defined a security baseline for Windows Server 2016 on Azure. This baseline is integrated into Azure Security Center by automatically reporting compliance once the OMS agent is installed and reporting to Security Center.

The detailed baseline can be found at the following link:

It contains over 100 configuration settings and the PowerShell DSC code for configuring them can be found in the file AzSC_CCEv4_WindowsServer2016.ps1.

Most of the settings in this baseline are a subset of the CIS benchmark and should also be thoroughly tested before applying it to production systems.

Windows Event Log and Audit Policy Best Practices

Our last hardening baseline contains best practice settings for configuring security logging on Windows:

  • Audit policy configuration
  • Windows Event log sizes
  • PowerShell logging

These best practices are based on guidelines from Malware Archeology:

The PowerShell DSC code for configuring them can be found in the file AuditPolicy_WindowsServer2016.ps1.

This baseline will have the least impact on a system because it only configures settings related to logging and audit settings.

Applying hardening baseline with PowerShell

Now that we have covered all the different baselines you can use, let’s have a look how to apply them.

We start with opening a PowerShell prompt with elevated privileges. Do not use PowerShell Core since PowerShell DSC is only supported in Windows PowerShell.

We need to import the PowerShell modules used in the baselines:

PowerShell DSC code needs to be compiled to a .mof file before it can used. We do this by running the .ps1 file. It creates a folder containing the compiled code.

Finally, we apply the hardening baseline to our system by referencing the previously created folder:

In this blogpost we gave more information about the code available in our NVISO-BE/posh-dsc-windowsserver-hardening GitHub repository and how to use it. Stay tuned for a next blogpost where we will use the PowerShell DSC code to automatically harden Windows Server virtual machines in Azure at deployment.

If you have questions about the above or the source code, don’t hesitate to reach out through an Issue on github!

4 thoughts on “Windows Server Hardening with PowerShell DSC

  1. Looks like some further testing needs to be done for the 2019 configurations published to GitHub. They result in a significant number of incorrectly configured registry entries. For example “WindowsNT” is not equivalent to “Windows NT”

  2. Encountered this error at the last step:

    The SendConfigurationApply function did not succeed. LCM failed to start desired state configuration manually.
    + CategoryInfo : NotSpecified: (root/Microsoft/…gurationManager:String) [], CimException
    + FullyQualifiedErrorId : MI RESULT 1
    + PSComputerName : localhost

Leave a Reply