[REQ-PAW-034] Disable Windows Script Host and Remap Scripting Extensions
Target Scope
- Applicable Systems: Privileged Access Workstations (PAWs - Dedicated Tier 0 Administrative Workstations). (For Tier 2 Client Workstations, refer to REQ-END-034; for Tier 0 Domain Controllers and Member Servers, refer to REQ-DC-159).
- Operating Systems: Windows 10 Enterprise (1809+), Windows 11 Enterprise (all supported builds).
Implementation Details
- Priority: High
- GPO Paths / Registry Locations:
- GPO Path (WSH Disable): Computer Configuration\Preferences\Windows Settings\Registry
- GPO Path (User Hive): User Configuration\Preferences\Windows Settings\Registry
- GPO Path (Associations): User Configuration\Preferences\Control Panel Settings\Folder Options
- Registry Locations:
HKLM\SOFTWARE\Microsoft\Windows Script Host\SettingsEnabled=0(REG_DWORD)TrustPolicy=2(REG_DWORD)
HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows Script Host\SettingsEnabled=0(REG_DWORD)TrustPolicy=2(REG_DWORD)
HKCU\SOFTWARE\Microsoft\Windows Script Host\SettingsEnabled=0(REG_DWORD)TrustPolicy=2(REG_DWORD)
HKLM\SOFTWARE\Classes\.<ext>(where<ext>=vbs,vbe,js,jse,wsf,wsh,hta)(Default)=txtfile(REG_SZ)
Rationale
Privileged Access Workstations (PAWs) serve as the dedicated management perimeter for Tier 0 Active Directory assets, enterprise PKI, and virtualization hosts. Because PAWs possess access tokens and administrative credentials with domain-wide authority, eliminating untrusted code execution pathways is paramount:
- Elimination of Legacy Scripting Engines: Windows Script Host (
wscript.exeandcscript.exe) executes legacy VBScript and JScript engines. These hosts are prominent Living-off-the-Land Binaries (LOLBins / LOLBAS) that offer attackers opportunities for defense evasion, memory injection, and unconstrained script execution (MITRE ATT&CK T1059.005, T1059.007, T1218). PAWs have no operational requirement for legacy script execution. - Defense-in-Depth Beyond Application Control: Even in environments where Windows Defender Application Control (WDAC) or AppLocker is deployed, disabling WSH at the registry engine layer ensures that
wscript.exeandcscript.exefail immediately upon invocation, preventing script execution even if policies are in audit mode or rule bypasses are attempted. - Comprehensive 64-Bit and WOW6432Node Lockdown: Attackers frequently execute 32-bit binaries (
%SystemRoot%\SysWOW64\wscript.exe) on 64-bit systems to bypass 64-bit security hooks. EnforcingEnabled = 0andTrustPolicy = 2across both native 64-bit and WOW6432Node registry paths ensures that 32-bit execution is completely disabled. - TrustPolicy Hardening: Configuring
TrustPolicy = 2ensures that even if WSH were selectively invoked, unsigned and untrusted scripts are disallowed system-wide. - Fail-Safe File Extension Remapping: Remapping
.vbs,.vbe,.js,.jse,.wsf,.wsh, and.htafile associations totxtfile(notepad.exe) ensures that if an administrator inspects an administrative script or artifact, opening the file in Windows Explorer displays the plain text in Notepad rather than executing the script.
Legacy Impact & Compatibility
- Administrative Scripting Dependencies: PAWs have zero tolerance for legacy VBScript or JScript administrative tooling. All Tier 0 administration must be executed via signed PowerShell 5.1+ scripts running under secure execution policies and Constrained Language Mode.
- Explorer Associations: Double-clicking on a
.vbsor.jsfile will open Notepad for inspection instead of running the script. - Execution Dialog: Any attempt to launch
wscript.exeorcscript.exedisplays a prompt stating that Windows Script Host is disabled on this machine.
Implementation Steps
Option A: Group Policy Object (GPO) Configuration (Preferred)
Step 1: Disable WSH via GPO Computer Preferences
- Open the Group Policy Management Console (
gpmc.msc). - Edit the PAW GPO (e.g.,
GPO_Hardening_PAW). - Navigate to:
Computer Configuration\Preferences\Windows Settings\Registry - Create a new Registry Item for the native 64-bit hive:
- Action:
Update - Hive:
HKEY_LOCAL_MACHINE - Key Path:
SOFTWARE\Microsoft\Windows Script Host\Settings - Value Name:
Enabled - Value Type:
REG_DWORD - Value Data:
0
- Action:
- Create a second Registry Item for
TrustPolicy:- Action:
Update - Hive:
HKEY_LOCAL_MACHINE - Key Path:
SOFTWARE\Microsoft\Windows Script Host\Settings - Value Name:
TrustPolicy - Value Type:
REG_DWORD - Value Data:
2
- Action:
- Create a third Registry Item for 32-bit WOW64 disablement:
- Action:
Update - Hive:
HKEY_LOCAL_MACHINE - Key Path:
SOFTWARE\WOW6432Node\Microsoft\Windows Script Host\Settings - Value Name:
Enabled - Value Type:
REG_DWORD - Value Data:
0
- Action:
- Create a fourth Registry Item for 32-bit WOW64 TrustPolicy:
- Action:
Update - Hive:
HKEY_LOCAL_MACHINE - Key Path:
SOFTWARE\WOW6432Node\Microsoft\Windows Script Host\Settings - Value Name:
TrustPolicy - Value Type:
REG_DWORD - Value Data:
2
- Action:
Step 2: Disable WSH in User Configuration Preferences
- Navigate to:
User Configuration\Preferences\Windows Settings\Registry - Create a new Registry Item:
- Action:
Update - Hive:
HKEY_CURRENT_USER - Key Path:
SOFTWARE\Microsoft\Windows Script Host\Settings - Value Name:
Enabled - Value Type:
REG_DWORD - Value Data:
0
- Action:
- Create a second Registry Item:
- Action:
Update - Hive:
HKEY_CURRENT_USER - Key Path:
SOFTWARE\Microsoft\Windows Script Host\Settings - Value Name:
TrustPolicy - Value Type:
REG_DWORD - Value Data:
2
- Action:
Step 3: Remap Script File Extensions to Notepad
- Navigate to:
User Configuration\Preferences\Control Panel Settings\Folder Options - Right-click and select New -> Open With:
- File Extension:
vbs - Associated Program:
%SystemRoot%\System32\notepad.exe - Set as default: Check
- File Extension:
- Repeat for
vbe,js,jse,wsf,wsh, andhta. - Alternatively, configure system-wide registry preferences under
HKLM\SOFTWARE\Classes\.<ext>setting the default string value totxtfile.
Option B: PowerShell & Registry Configuration (Remediation / Non-GPO)
Configure the local registry settings to disable WSH and remap associations.
Download Script: Disable-PawWsh.ps1
# Disable-PawWsh.ps1
# Description: Disables Windows Script Host globally across 64-bit and 32-bit registry hives, enforces TrustPolicy, and remaps script file associations to Notepad on PAWs.
Write-Host "Applying Windows Script Host and file association hardening for PAWs..." -ForegroundColor Cyan
# 1. Disable WSH globally in 64-bit HKLM
$RegistryHklm = "HKLM:\SOFTWARE\Microsoft\Windows Script Host\Settings"
if (-not (Test-Path $RegistryHklm)) {
New-Item -Path $RegistryHklm -Force | Out-Null
}
Set-ItemProperty -Path $RegistryHklm -Name "Enabled" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $RegistryHklm -Name "TrustPolicy" -Value 2 -Type DWord -Force
Write-Host "[+] WSH globally disabled and TrustPolicy enforced in HKLM." -ForegroundColor Green
# 2. Disable WSH in WOW6432Node on 64-bit systems
if ([Environment]::Is64BitOperatingSystem) {
$RegistryWow64 = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Script Host\Settings"
if (-not (Test-Path $RegistryWow64)) {
New-Item -Path $RegistryWow64 -Force | Out-Null
}
Set-ItemProperty -Path $RegistryWow64 -Name "Enabled" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $RegistryWow64 -Name "TrustPolicy" -Value 2 -Type DWord -Force
Write-Host "[+] WSH globally disabled and TrustPolicy enforced in HKLM WOW6432Node." -ForegroundColor Green
}
# 3. Disable WSH in current user HKCU hive
$RegistryHkcu = "HKCU:\SOFTWARE\Microsoft\Windows Script Host\Settings"
if (-not (Test-Path $RegistryHkcu)) {
New-Item -Path $RegistryHkcu -Force | Out-Null
}
Set-ItemProperty -Path $RegistryHkcu -Name "Enabled" -Value 0 -Type DWord -Force
Set-ItemProperty -Path $RegistryHkcu -Name "TrustPolicy" -Value 2 -Type DWord -Force
Write-Host "[+] WSH disabled in current user HKCU hive." -ForegroundColor Green
# 4. Remap script file extensions to notepad
$Extensions = @("vbs", "vbe", "js", "jse", "wsf", "wsh", "hta")
foreach ($Ext in $Extensions) {
$ProgIdPath = "HKLM:\SOFTWARE\Classes\.$Ext"
# Update Class Association to Notepad
if (-not (Test-Path $ProgIdPath)) {
New-Item -Path $ProgIdPath -Force | Out-Null
}
Set-ItemProperty -Path $ProgIdPath -Name "" -Value "txtfile" -Type String -Force
Write-Host " Mapped .$Ext extension to txtfile handler." -ForegroundColor Gray
}
Write-Host "[+] Script file extension handlers mapped to Notepad." -ForegroundColor Green
To verify the WSH configuration state:
Download Script: Get-PawWshStatus.ps1
# Get-PawWshStatus.ps1
# Description: Audits Windows Script Host registry state across 64-bit and 32-bit hives and script file extension association handlers on PAWs.
Write-Host "--- Auditing Windows Script Host Hardening on PAWs ---" -ForegroundColor Cyan
$script:Vulnerable = $false
# 1. Audit WSH Registry settings in 64-bit HKLM
$RegistryHklm = "HKLM:\SOFTWARE\Microsoft\Windows Script Host\Settings"
if (Test-Path $RegistryHklm) {
$ValHklm = (Get-ItemProperty -Path $RegistryHklm -Name "Enabled" -ErrorAction SilentlyContinue).Enabled
if ($ValHklm -eq 0) {
Write-Host " - HKLM WSH Enabled: 0 (Secure)" -ForegroundColor Green
} else {
Write-Host " - VULNERABLE: HKLM WSH is enabled or not configured (Value: '$($ValHklm)')" -ForegroundColor Red
$script:Vulnerable = $true
}
$TrustHklm = (Get-ItemProperty -Path $RegistryHklm -Name "TrustPolicy" -ErrorAction SilentlyContinue).TrustPolicy
if ($TrustHklm -eq 2) {
Write-Host " - HKLM WSH TrustPolicy: 2 (Secure)" -ForegroundColor Green
} else {
Write-Host " - VULNERABLE: HKLM WSH TrustPolicy is not set to 2 (Value: '$($TrustHklm)')" -ForegroundColor Red
$script:Vulnerable = $true
}
} else {
Write-Host " - VULNERABLE: HKLM WSH settings key is missing (Expected: Enabled = 0, TrustPolicy = 2)" -ForegroundColor Red
$script:Vulnerable = $true
}
# 2. Audit WSH Registry settings in WOW6432Node on 64-bit systems
if ([Environment]::Is64BitOperatingSystem) {
$RegistryWow64 = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Script Host\Settings"
if (Test-Path $RegistryWow64) {
$ValWow64 = (Get-ItemProperty -Path $RegistryWow64 -Name "Enabled" -ErrorAction SilentlyContinue).Enabled
if ($ValWow64 -eq 0) {
Write-Host " - WOW6432Node WSH Enabled: 0 (Secure)" -ForegroundColor Green
} else {
Write-Host " - VULNERABLE: WOW6432Node WSH is enabled or not configured (Value: '$($ValWow64)')" -ForegroundColor Red
$script:Vulnerable = $true
}
$TrustWow64 = (Get-ItemProperty -Path $RegistryWow64 -Name "TrustPolicy" -ErrorAction SilentlyContinue).TrustPolicy
if ($TrustWow64 -eq 2) {
Write-Host " - WOW6432Node WSH TrustPolicy: 2 (Secure)" -ForegroundColor Green
} else {
Write-Host " - VULNERABLE: WOW6432Node WSH TrustPolicy is not set to 2 (Value: '$($TrustWow64)')" -ForegroundColor Red
$script:Vulnerable = $true
}
} else {
Write-Host " - VULNERABLE: WOW6432Node WSH settings key is missing (Expected: Enabled = 0, TrustPolicy = 2)" -ForegroundColor Red
$script:Vulnerable = $true
}
}
# 3. Audit file associations
$Extensions = @("vbs", "vbe", "js", "jse", "wsf", "wsh", "hta")
foreach ($Ext in $Extensions) {
$ProgIdPath = "HKLM:\SOFTWARE\Classes\.$Ext"
if (Test-Path $ProgIdPath) {
$Handler = (Get-ItemProperty -Path $ProgIdPath -Name "" -ErrorAction SilentlyContinue).""
if ($Handler -eq "txtfile" -or $Handler -match "notepad") {
Write-Host " - Extension .$Ext Handler: $Handler (Secure)" -ForegroundColor Green
} else {
Write-Host " - VULNERABLE: Extension .$Ext Handler is '$($Handler)' (Expected: txtfile/notepad)" -ForegroundColor Red
$script:Vulnerable = $true
}
} else {
Write-Host " - VULNERABLE: Extension .$Ext Class Registry key not found." -ForegroundColor Red
$script:Vulnerable = $true
}
}
if ($script:Vulnerable) {
Write-Host "[-] Audit Result: VULNERABLE - Windows Script Host hardening controls on PAW do not meet baseline requirements." -ForegroundColor Red
} else {
Write-Host "[+] Audit Result: SECURE - Windows Script Host hardening controls on PAW are fully compliant." -ForegroundColor Green
}
Sources & Compliance References
- ANSSI AD Hardening Guide: Recommendations Section 3.1.2 (System hardening and OS minimization) / DAT-NT-13 Note Technique.
- DoD Windows 11 Computer STIG v2r6: Rule
V-219661(Windows Script Host must be disabled). - DoD Windows 10 Computer STIG: Rule
V-63825(Configure Windows Script Host to prevent execution of untrusted scripts). - CIS Microsoft Windows Client Benchmark: Section 18.9 (Administrative Templates: System - Script Execution Restrictions).
- Microsoft Learn: Windows Script Host Settings and Security Guidelines.