Introduction to Compliance Configuration on Windows Server 2019

Configuring Windows Server 2019 for compliance involves implementing technical controls that satisfy the requirements of regulatory frameworks such as PCI DSS, HIPAA, SOC 2, NIST 800-53, ISO 27001, CIS Benchmarks, and DISA STIGs. Compliance configuration encompasses access controls, encryption, auditing, patch management, system hardening, and documentation. Windows Server 2019 includes built-in tools and features that directly address many compliance requirements. Compliance is not a one-time event but an ongoing process requiring continuous monitoring, periodic assessments, and remediation of identified gaps. This guide covers the technical implementation of key compliance controls commonly required across multiple frameworks.

Assessing Compliance with Security Configuration Management

Use the Security Compliance Toolkit and Microsoft Security Baselines to assess current compliance posture. Download the Windows Server 2019 Security Baseline and use the Policy Analyzer tool to compare current settings against the baseline. Export current security settings for assessment:

secedit /export /cfg C:ComplianceReportsCurrentSettings.cfg /areas SECURITYPOLICY,USER_RIGHTS,REGKEYS,FILESTORE,SERVICES
auditpol /backup /file:C:ComplianceReportsAuditPolicy.csv

Run LGPO (Local Group Policy Object tool) from the SCT to import security baselines:

LGPO.exe /g "C:BaselinesWS2019GPOsComputer{GUID}"
LGPO.exe /parse /m "C:BaselinesWS2019GPOsComputer{GUID}DomainSysvolGPOMachinemicrosoftwindows ntSecEditGptTmpl.inf" > C:ComplianceReportsBaselineParse.txt

Implementing CIS Benchmark Controls

The CIS Benchmark for Windows Server 2019 provides specific, testable recommendations. Level 1 controls are minimum security recommendations appropriate for all systems. Level 2 adds more restrictive settings for high-security environments. Key Level 1 registry settings to configure:

# Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is enabled
reg add "HKLMSYSTEMCurrentControlSetControlLsa" /v "RestrictAnonymousSAM" /t REG_DWORD /d 1 /f
# Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is enabled
reg add "HKLMSYSTEMCurrentControlSetControlLsa" /v "RestrictAnonymous" /t REG_DWORD /d 1 /f
# Ensure 'Network security: LAN Manager authentication level' is set to NTLMv2 only
reg add "HKLMSYSTEMCurrentControlSetControlLsa" /v "LmCompatibilityLevel" /t REG_DWORD /d 5 /f
# Ensure 'Network security: Minimum session security for NTLM SSP clients' requires 128-bit encryption
reg add "HKLMSYSTEMCurrentControlSetControlLsaMSV1_0" /v "NTLMMinClientSec" /t REG_DWORD /d 537395200 /f
# Disable LM hashes
reg add "HKLMSYSTEMCurrentControlSetControlLsa" /v "NoLMHash" /t REG_DWORD /d 1 /f

Configuring TLS and Cipher Suite Compliance

Disable outdated TLS and SSL protocols and weak cipher suites to comply with PCI DSS requirement 4.1 and NIST SP 800-52. Disable SSLv2, SSLv3, TLS 1.0, and TLS 1.1:

$protocols = @("SSL 2.0","SSL 3.0","TLS 1.0","TLS 1.1")
foreach ($protocol in $protocols) {
    $serverPath = "HKLM:SYSTEMCurrentControlSetControlSecurityProvidersSCHANNELProtocols$protocolServer"
    $clientPath = "HKLM:SYSTEMCurrentControlSetControlSecurityProvidersSCHANNELProtocols$protocolClient"
    New-Item -Path $serverPath -Force | Out-Null
    New-Item -Path $clientPath -Force | Out-Null
    Set-ItemProperty -Path $serverPath -Name "Enabled" -Value 0
    Set-ItemProperty -Path $serverPath -Name "DisabledByDefault" -Value 1
    Set-ItemProperty -Path $clientPath -Name "Enabled" -Value 0
    Set-ItemProperty -Path $clientPath -Name "DisabledByDefault" -Value 1
}
# Enable TLS 1.2 and 1.3 explicitly
$enableProtocols = @("TLS 1.2","TLS 1.3")
foreach ($protocol in $enableProtocols) {
    $serverPath = "HKLM:SYSTEMCurrentControlSetControlSecurityProvidersSCHANNELProtocols$protocolServer"
    $clientPath = "HKLM:SYSTEMCurrentControlSetControlSecurityProvidersSCHANNELProtocols$protocolClient"
    New-Item -Path $serverPath -Force | Out-Null
    New-Item -Path $clientPath -Force | Out-Null
    Set-ItemProperty -Path $serverPath -Name "Enabled" -Value 1
    Set-ItemProperty -Path $serverPath -Name "DisabledByDefault" -Value 0
    Set-ItemProperty -Path $clientPath -Name "Enabled" -Value 1
    Set-ItemProperty -Path $clientPath -Name "DisabledByDefault" -Value 0
}

Disable weak cipher suites using IISCrypto or PowerShell. Disable RC4, DES, 3DES, and MD5-based ciphers:

$weakCiphers = @("RC4 128/128","RC4 64/128","RC4 40/128","RC4 56/128","DES 56/56","Triple DES 168")
foreach ($cipher in $weakCiphers) {
    $path = "HKLM:SYSTEMCurrentControlSetControlSecurityProvidersSCHANNELCiphers$cipher"
    New-Item -Path $path -Force | Out-Null
    Set-ItemProperty -Path $path -Name "Enabled" -Value 0
}

Implementing FIPS 140-2 Mode

Federal information systems and organizations handling government data may need to enable FIPS 140-2 mode, which restricts cryptographic operations to FIPS-approved algorithms. Note that enabling FIPS mode can break some applications. Test thoroughly before enabling in production:

reg add "HKLMSYSTEMCurrentControlSetControlLsaFipsAlgorithmPolicy" /v "Enabled" /t REG_DWORD /d 1 /f
Set-ItemProperty -Path "HKLM:SYSTEMCurrentControlSetControlLsaFipsAlgorithmPolicy" -Name "Enabled" -Value 1

Via Group Policy: Computer Configuration > Windows Settings > Security Settings > Local Policies > Security Options > System cryptography: Use FIPS compliant algorithms for encryption, hashing, and signing = Enabled.

Configuring Patch Management Compliance

Regular patching is required by virtually all compliance frameworks. Configure Windows Update for Business or WSUS for automated patch management. Check current patch level and pending updates:

Get-HotFix | Sort-Object InstalledOn -Descending | Select-Object HotFixID, Description, InstalledOn -First 20
$wu = New-Object -ComObject Microsoft.Update.Session
$searcher = $wu.CreateUpdateSearcher()
$results = $searcher.Search("IsInstalled=0 and IsHidden=0")
$results.Updates | Select-Object Title, IsDownloaded, IsInstalled | Format-Table

Configure automatic updates via registry for critical and security updates:

reg add "HKLMSOFTWAREPoliciesMicrosoftWindowsWindowsUpdateAU" /v "AUOptions" /t REG_DWORD /d 3 /f
reg add "HKLMSOFTWAREPoliciesMicrosoftWindowsWindowsUpdateAU" /v "AutomaticMaintenanceEnabled" /t REG_DWORD /d 1 /f
reg add "HKLMSOFTWAREPoliciesMicrosoftWindowsWindowsUpdateAU" /v "ScheduledInstallDay" /t REG_DWORD /d 0 /f
reg add "HKLMSOFTWAREPoliciesMicrosoftWindowsWindowsUpdateAU" /v "ScheduledInstallTime" /t REG_DWORD /d 3 /f

Configuring Data Classification and DLP

Data classification is required by HIPAA and GDPR to identify and protect sensitive data. Windows Server 2019 includes File Classification Infrastructure (FCI) through File Server Resource Manager (FSRM). Install FSRM and configure classification rules:

Install-WindowsFeature FS-Resource-Manager -IncludeManagementTools
New-FsrmClassificationPropertyDefinition -Name "Confidentiality" -DisplayName "Confidentiality Level" -Type Enum -PossibleValue @("Public","Internal","Confidential","Restricted") -Description "Data confidentiality level"
New-FsrmClassificationRule -Name "PII Detection" -Property "Confidentiality" -PropertyValue "Confidential" -ContentRegularExpression @("d{3}-d{2}-d{4}","[0-9]{16}") -Namespace @("[D:]")

Compliance Reporting and Documentation

Generate compliance reports to demonstrate adherence to security controls. Use PowerShell to create automated compliance reports:

$report = [ordered]@{
    "Hostname" = $env:COMPUTERNAME
    "OS Version" = (Get-CimInstance Win32_OperatingSystem).Caption
    "Last Boot" = (Get-CimInstance Win32_OperatingSystem).LastBootUpTime
    "BitLocker Status" = (Get-BitLockerVolume -MountPoint "C:").ProtectionStatus
    "Defender Enabled" = (Get-MpComputerStatus).RealTimeProtectionEnabled
    "SMBv1 Disabled" = -not (Get-SmbServerConfiguration).EnableSMB1Protocol
    "Firewall Enabled" = (Get-NetFirewallProfile -Profile Domain).Enabled
    "Last Patch Date" = (Get-HotFix | Sort-Object InstalledOn | Select-Object -Last 1).InstalledOn
    "Local Admin Count" = (Get-LocalGroupMember -Group "Administrators").Count
    "Remote Desktop" = (Get-ItemProperty "HKLM:SYSTEMCurrentControlSetControlTerminal Server").fDenyTSConnections
}
$report | Out-File "C:ComplianceReportsComplianceSnapshot_$(Get-Date -Format yyyyMMdd).txt"
$report | ConvertTo-Json | Out-File "C:ComplianceReportsComplianceSnapshot_$(Get-Date -Format yyyyMMdd).json"