How to Configure Windows Server 2019 Registry Settings
The Windows Registry is a hierarchical database that stores configuration settings for the operating system, hardware, applications, and user profiles. Many Windows Server 2019 configurations that are not exposed through GUI interfaces are controlled exclusively through registry values. Understanding registry structure, safely reading and modifying values, using PowerShell for registry automation, and applying registry changes through Group Policy are essential skills for server administration.
Registry Structure and Key Hives
The registry is organised into five root hives. HKEY_LOCAL_MACHINE (HKLM) contains hardware and system-wide configuration. HKEY_CURRENT_USER (HKCU) stores settings for the currently logged-in user. HKEY_USERS (HKU) stores profiles for all user accounts. HKEY_CLASSES_ROOT (HKCR) contains file association and COM object registrations. HKEY_CURRENT_CONFIG (HKCC) holds current hardware profile information. Each hive contains keys (similar to folders) and values (name-type-data pairs). Value types include REG_SZ (string), REG_DWORD (32-bit integer), REG_QWORD (64-bit integer), REG_BINARY (binary data), REG_MULTI_SZ (multi-string), and REG_EXPAND_SZ (expandable string with environment variables).
Reading Registry Values with PowerShell
PowerShell exposes the registry as a provider (like the filesystem), accessible via Get-Item, Get-ItemProperty, and the Reg: PSDrive.
# Read a registry key and all its values
Get-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersion"
# Read a specific value
Get-ItemPropertyValue -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersion" -Name "ProductName"
# Read all values from a registry key and display as a table
Get-ItemProperty -Path "HKLM:SYSTEMCurrentControlSetControlTerminal Server" |
Get-Member -MemberType NoteProperty |
ForEach-Object {
$Name = $_.Name
$Value = (Get-ItemProperty -Path "HKLM:SYSTEMCurrentControlSetControlTerminal Server").$Name
[PSCustomObject]@{ Name = $Name; Value = $Value }
} | Where-Object { $_.Name -notlike "PS*" } | Format-Table -AutoSize
# Check if a registry key exists
Test-Path -Path "HKLM:SOFTWAREMyApplication"
# Check if a value exists
$Key = Get-Item -Path "HKLM:SOFTWAREMyApplication" -ErrorAction SilentlyContinue
if ($Key -and $Key.GetValue("InstallPath")) {
Write-Host "InstallPath value exists"
}
Writing Registry Values with PowerShell
# Create a new registry key
New-Item -Path "HKLM:SOFTWAREMyCompanyMyApp" -Force
# Create or update a registry value (REG_SZ string)
Set-ItemProperty -Path "HKLM:SOFTWAREMyCompanyMyApp" -Name "InstallPath" -Value "C:Program FilesMyApp"
# Create a DWORD value
Set-ItemProperty -Path "HKLM:SOFTWAREMyCompanyMyApp" -Name "MaxConnections" -Value 100 -Type DWord
# Create a QWORD value (64-bit)
Set-ItemProperty -Path "HKLM:SOFTWAREMyCompanyMyApp" -Name "MaxFileSize" -Value 4294967296 -Type QWord
# Create a multi-string value (REG_MULTI_SZ)
Set-ItemProperty -Path "HKLM:SOFTWAREMyCompanyMyApp" -Name "AllowedHosts" -Value @("server01", "server02", "server03") -Type MultiString
# Create an expandable string (REG_EXPAND_SZ)
Set-ItemProperty -Path "HKLM:SOFTWAREMyCompanyMyApp" -Name "LogPath" -Value "%SYSTEMDRIVE%LogsMyApp" -Type ExpandString
# Create a new value with New-ItemProperty
New-ItemProperty -Path "HKLM:SOFTWAREMyCompanyMyApp" -Name "Version" -Value "2.5.0" -PropertyType String -Force
Important Security Registry Settings
Many Windows Server 2019 security hardening steps involve registry modifications. The following are commonly required hardening registry settings.
# Disable SMBv1 (security hardening)
Set-ItemProperty -Path "HKLM:SYSTEMCurrentControlSetServicesLanmanServerParameters" `
-Name "SMB1" -Value 0 -Type DWord
# Disable LLMNR
New-Item -Path "HKLM:SOFTWAREPoliciesMicrosoftWindows NTDNSClient" -Force
Set-ItemProperty -Path "HKLM:SOFTWAREPoliciesMicrosoftWindows NTDNSClient" `
-Name "EnableMulticast" -Value 0 -Type DWord
# Disable NetBIOS over TCP/IP for all adapters
$Adapters = Get-ChildItem "HKLM:SYSTEMCurrentControlSetServicesNetBTParametersInterfaces"
foreach ($Adapter in $Adapters) {
Set-ItemProperty -Path $Adapter.PSPath -Name "NetbiosOptions" -Value 2 -Type DWord
}
# Disable remote registry auto-start (leave as manual)
Set-Service -Name RemoteRegistry -StartupType Manual
Stop-Service -Name RemoteRegistry -Force
# Require SMB signing
Set-ItemProperty -Path "HKLM:SYSTEMCurrentControlSetServicesLanmanServerParameters" `
-Name "RequireSecuritySignature" -Value 1 -Type DWord
Set-ItemProperty -Path "HKLM:SYSTEMCurrentControlSetServicesLanmanWorkstationParameters" `
-Name "RequireSecuritySignature" -Value 1 -Type DWord
Performance Registry Settings
# Configure large system cache for file servers
Set-ItemProperty -Path "HKLM:SYSTEMCurrentControlSetControlSession ManagerMemory Management" `
-Name "LargeSystemCache" -Value 1 -Type DWord
# Increase IRPStackSize for network operations under heavy load
Set-ItemProperty -Path "HKLM:SYSTEMCurrentControlSetServicesLanmanServerParameters" `
-Name "IRPStackSize" -Value 32 -Type DWord
# Disable 8.3 file name creation on NTFS (improves directory scan performance)
Set-ItemProperty -Path "HKLM:SYSTEMCurrentControlSetControlFileSystem" `
-Name "NtfsDisable8dot3NameCreation" -Value 1 -Type DWord
# Configure TCP auto-tuning for high-throughput networks
netsh interface tcp set global autotuninglevel=normal
Registry Backup and Restore
# Export a registry key to a .reg file
reg export "HKLMSOFTWAREMyCompanyMyApp" "C:BackupMyApp_registry_backup.reg"
# Export the entire HKLM hive (use carefully - can be very large)
reg export HKLM "C:BackupHKLM_full.reg"
# Import a registry file
reg import "C:BackupMyApp_registry_backup.reg"
# Export a specific key via PowerShell
$KeyPath = "HKLM:SOFTWAREMyCompanyMyApp"
$ExportPath = "C:BackupMyApp_backup.xml"
Get-ItemProperty -Path $KeyPath | Export-Clixml -Path $ExportPath
# Create a system restore point before making changes
Checkpoint-Computer -Description "Before registry changes" -RestorePointType MODIFY_SETTINGS
Deleting Registry Keys and Values
# Delete a single value
Remove-ItemProperty -Path "HKLM:SOFTWAREMyCompanyMyApp" -Name "ObsoleteSetting"
# Delete an entire registry key (including subkeys)
Remove-Item -Path "HKLM:SOFTWAREMyCompanyOldApp" -Recurse -Force
# Confirm before deleting
$KeyToDelete = "HKLM:SOFTWAREMyCompanyOldApp"
if (Test-Path $KeyToDelete) {
Remove-Item -Path $KeyToDelete -Recurse -Confirm
}
Editing Remote Registry
# Access registry on a remote machine (requires Remote Registry service)
# Start Remote Registry on the remote server if needed
Invoke-Command -ComputerName "WEBSVR01" -ScriptBlock { Start-Service RemoteRegistry }
# Read a remote registry value
Invoke-Command -ComputerName "WEBSVR01" -ScriptBlock {
Get-ItemPropertyValue -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersion" -Name "ProductName"
}
# Write to remote registry
Invoke-Command -ComputerName "WEBSVR01" -ScriptBlock {
Set-ItemProperty -Path "HKLM:SOFTWAREMyApp" -Name "ServerMode" -Value "Production"
}
Auditing Registry Access
# Enable auditing on a specific registry key
# This requires configuring the key's SACL (System Access Control List)
$RegPath = "HKLM:SOFTWAREMyCompanyMyApp"
$Key = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey("SOFTWAREMyCompanyMyApp", [Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree, [System.Security.AccessControl.RegistryRights]::ChangePermissions)
$AuditRule = New-Object System.Security.AccessControl.RegistryAuditRule(
"Everyone",
[System.Security.AccessControl.RegistryRights]::SetValue,
[System.Security.AccessControl.AuditFlags]::Success
)
$ACL = $Key.GetAccessControl([System.Security.AccessControl.AccessControlSections]::Audit)
$ACL.AddAuditRule($AuditRule)
$Key.SetAccessControl($ACL)
$Key.Close()
Write-Host "Registry auditing configured for $RegPath"
Conclusion
The Windows Registry is a central configuration repository for Windows Server 2019, and PowerShell provides the most efficient means of reading, writing, and managing registry settings at scale. Security hardening, performance tuning, application configuration, and remote administration all leverage registry operations. Always backup registry keys before making changes, use Set-ItemProperty rather than manual edits for scriptable operations, and audit sensitive registry keys containing security-relevant configuration to detect unauthorised modification attempts.