Windows Defender Credential Guard is a powerful security feature that uses virtualization-based security (VBS) to isolate secrets (like NTLM hashes or Kerberos tickets). By moving these credentials into a secure, virtualized container, Credential Guard prevents "Pass-the-Hash" and other identity-theft attacks, even if the main Windows kernel is compromised. For IT auditors and security engineers, verifying that Credential Guard is active is a cornerstone of modern system hardening.
This guide explains how to check its status using the registry and PowerShell via Batch.
Why Validate Credential Guard?
- Identity Theft Prevention: Ensuring that your administrative and user credentials aren't vulnerable to discovery by memory-harvesting tools like Mimikatz.
- Security Compliance Audit: Meeting the requirements for NIST, CIS, or internal corporate security standards.
- Troubleshooting: Identifying if a legacy application is failing because it requires access to credential types that Credential Guard intentionally blocks.
Method 1: Using the Registry (Fastest)
Windows stores the configuration for Credential Guard in the Local Security Authority (LSA) registry keys.
@echo off
setlocal
set "REG_K=HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa"
echo [PROCESS] Querying LSA for Credential Guard configuration...
set "FLAG="
for /f "tokens=3" %%a in ('reg query "%REG_K%" /v LsaCfgFlags 2^>nul ^| findstr /i "LsaCfgFlags"') do set "FLAG=%%a"
if not defined FLAG (
echo [INFO] Credential Guard is not configured in the registry.
echo [NOTE] The LsaCfgFlags value does not exist.
) else (
echo Configuration Flag: %FLAG%
if "%FLAG%"=="0x1" echo [STATUS] Credential Guard is CONFIGURED ^(with UEFI Lock^).
if "%FLAG%"=="0x2" echo [STATUS] Credential Guard is CONFIGURED ^(without UEFI Lock^).
if "%FLAG%"=="0x0" echo [STATUS] Credential Guard is DISABLED in registry.
echo.
echo [NOTE] This shows the configuration only. Use Method 2 to verify
echo that Credential Guard is actually running.
)
pauseMethod 2: Using WMI via PowerShell (Most Reliable)
The most accurate way to see if Credential Guard is actually running (rather than just configured) is to query the Win32_DeviceGuard WMI class.
@echo off
setlocal
:: Check for admin rights
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Administrator privileges are required for an accurate query.
pause
exit /b 1
)
echo [PROCESS] Retrieving Device Guard Runtime Status...
echo.
powershell -NoProfile -Command ^
"$dg = Get-CimInstance -Namespace root\Microsoft\Windows\DeviceGuard -ClassName Win32_DeviceGuard -ErrorAction SilentlyContinue;" ^
"if (-not $dg) {" ^
" Write-Host '[ERROR] DeviceGuard WMI class not available.';" ^
" Write-Host '[NOTE] This feature may not be supported on this Windows edition.';" ^
" exit 1" ^
"};" ^
"$running = $dg.SecurityServicesRunning;" ^
"if ($running -contains 1) {" ^
" Write-Host '[SUCCESS] Credential Guard is ACTIVE and protecting the system.'" ^
"} else {" ^
" Write-Host '[WARNING] Credential Guard is NOT currently running.';" ^
" Write-Host '[HELP] Verify that VBS is enabled, Secure Boot is active,';" ^
" Write-Host ' and virtualization is enabled in BIOS/UEFI.'" ^
"}" 2>nul
pauseCreating a Security Readiness Auditor
A professional script checks the configuration, hardware readiness, and runtime status to provide a complete report.
@echo off
setlocal EnableDelayedExpansion
echo ============================================================
echo Credential Guard Infrastructure Auditor
echo ============================================================
echo.
echo Computer: %COMPUTERNAME%
echo Date: %date% %time%
echo.
echo ============================================================
:: ============================================================
:: Check Administrator Privileges
:: ============================================================
echo.
echo [PREREQ] Checking administrator privileges...
net session >nul 2>&1
if !errorlevel! neq 0 (
echo [ERROR] Administrator privileges required. >&2
echo.
echo Right-click and select "Run as administrator"
pause
exit /b 1
)
echo [OK] Running with administrator privileges
echo.
:: ============================================================
:: Check 1: Registry Configuration
:: ============================================================
echo ============================================================
echo Check 1: Registry Configuration
echo ============================================================
echo.
set "RegKey=HKLM\SYSTEM\CurrentControlSet\Control\Lsa"
set "RegValue=LsaCfgFlags"
set "FLAG="
:: Query registry value
for /f "skip=2 tokens=3" %%a in (
'reg query "%RegKey%" /v %RegValue% 2^>nul'
) do set "FLAG=%%a"
echo [INFO] Registry Key: %RegKey%
echo [INFO] Value Name: %RegValue%
echo.
if not defined FLAG (
echo [RESULT] NOT CONFIGURED
echo.
echo - LsaCfgFlags registry value not set
echo - Credential Guard is not enabled via registry
echo - May still be enabled via Group Policy
set "RegStatus=NOT_CONFIGURED"
) else if "!FLAG!"=="0x1" (
echo [RESULT] CONFIGURED WITH UEFI LOCK
echo.
echo - Value: 0x1
echo - Credential Guard enabled with UEFI lock
echo - Cannot be disabled without physical BIOS access
echo - Maximum security configuration
set "RegStatus=CONFIGURED_LOCKED"
) else if "!FLAG!"=="0x2" (
echo [RESULT] CONFIGURED WITHOUT UEFI LOCK
echo.
echo - Value: 0x2
echo - Credential Guard enabled without UEFI lock
echo - Can be disabled via registry/policy
set "RegStatus=CONFIGURED_UNLOCKED"
) else if "!FLAG!"=="0x0" (
echo [RESULT] EXPLICITLY DISABLED
echo.
echo - Value: 0x0
echo - Credential Guard explicitly disabled
set "RegStatus=DISABLED"
) else (
echo [RESULT] UNKNOWN VALUE
echo.
echo - Value: !FLAG!
echo - Non-standard configuration
set "RegStatus=UNKNOWN"
)
echo.
:: ============================================================
:: Check 2: Runtime Status via WMI
:: ============================================================
echo ============================================================
echo Check 2: Runtime Status (DeviceGuard WMI)
echo ============================================================
echo.
:: Build PowerShell script for better readability
set "PSScript=%TEMP%\cg_audit_%RANDOM%.ps1"
(
echo try {
echo $dg = Get-CimInstance -Namespace root\Microsoft\Windows\DeviceGuard -ClassName Win32_DeviceGuard -ErrorAction Stop
echo.
echo Write-Host "[INFO] DeviceGuard WMI class found"
echo Write-Host ""
echo.
echo # ===== Virtualization-Based Security =====
echo Write-Host "Virtualization-Based Security (VBS^):"
echo $vbs = $dg.VirtualizationBasedSecurityStatus
echo.
echo switch ($vbs^) {
echo 0 { Write-Host " [FAIL] Status: NOT ENABLED" -ForegroundColor Red }
echo 1 { Write-Host " [WARN] Status: ENABLED but not running" -ForegroundColor Yellow }
echo 2 { Write-Host " [PASS] Status: RUNNING" -ForegroundColor Green }
echo default { Write-Host " [INFO] Status: Unknown ($vbs^)" }
echo }
echo Write-Host ""
echo.
echo # ===== Credential Guard =====
echo Write-Host "Credential Guard:"
echo.
echo $cgRunning = $dg.SecurityServicesRunning -contains 1
echo $cgConfigured = $dg.SecurityServicesConfigured -contains 1
echo.
echo if ($cgRunning^) {
echo Write-Host " [PASS] Status: ACTIVE AND RUNNING" -ForegroundColor Green
echo } elseif ($cgConfigured^) {
echo Write-Host " [WARN] Status: CONFIGURED but not running" -ForegroundColor Yellow
echo Write-Host " [INFO] May require reboot to activate"
echo } else {
echo Write-Host " [FAIL] Status: NOT CONFIGURED" -ForegroundColor Red
echo }
echo Write-Host ""
echo.
echo # ===== HVCI (Hypervisor-Protected Code Integrity^) =====
echo Write-Host "HVCI (Hypervisor Code Integrity^):"
echo.
echo $hvciRunning = $dg.SecurityServicesRunning -contains 2
echo $hvciConfigured = $dg.SecurityServicesConfigured -contains 2
echo.
echo if ($hvciRunning^) {
echo Write-Host " [PASS] Status: ACTIVE" -ForegroundColor Green
echo } elseif ($hvciConfigured^) {
echo Write-Host " [WARN] Status: CONFIGURED but not running" -ForegroundColor Yellow
echo } else {
echo Write-Host " [INFO] Status: NOT CONFIGURED"
echo }
echo Write-Host ""
echo.
echo # ===== Security Properties =====
echo Write-Host "Security Properties:"
echo Write-Host " Required: $($dg.RequiredSecurityProperties -join ', ')"
echo Write-Host " Available: $($dg.AvailableSecurityProperties -join ', ')"
echo Write-Host ""
echo.
echo # ===== Exit with status =====
echo if ($cgRunning -and ($vbs -eq 2^)^) {
echo exit 0 # All good
echo } elseif ($cgConfigured^) {
echo exit 1 # Configured but not running
echo } else {
echo exit 2 # Not configured
echo }
echo.
echo } catch {
echo Write-Host "[FAIL] DeviceGuard WMI class not available" -ForegroundColor Red
echo Write-Host ""
echo Write-Host "Possible reasons:" -ForegroundColor Yellow
echo Write-Host " - Windows edition does not support Credential Guard"
echo Write-Host " - Minimum: Windows 10 Enterprise/Education, Windows 11 Pro/Enterprise"
echo Write-Host " - DeviceGuard feature not installed"
echo Write-Host " - WMI service issues"
echo Write-Host ""
echo exit 3
echo }
) > "%PSScript%"
:: Execute PowerShell script
powershell -NoProfile -ExecutionPolicy Bypass -File "%PSScript%"
set "PSResult=!errorlevel!"
:: Cleanup
del "%PSScript%" >nul 2>&1
echo.
:: ============================================================
:: Check 3: UEFI/Firmware Requirements
:: ============================================================
echo ============================================================
echo Check 3: Hardware/Firmware Requirements
echo ============================================================
echo.
echo [INFO] Checking system requirements...
echo.
:: Check firmware type (UEFI vs BIOS)
set "FirmwareType="
for /f "skip=1 tokens=2*" %%a in (
'bcdedit /enum {current} ^| findstr /i "path"'
) do (
echo %%a %%b | findstr /i "efi" >nul
if !errorlevel! equ 0 set "FirmwareType=UEFI"
)
if not defined FirmwareType set "FirmwareType=BIOS"
echo Firmware Type: !FirmwareType!
if "!FirmwareType!"=="UEFI" (
echo [PASS] UEFI firmware detected (required for Credential Guard^)
) else (
echo [FAIL] Legacy BIOS detected
echo [INFO] Credential Guard requires UEFI firmware
)
echo.
:: Check virtualization support
echo Virtualization:
systeminfo | findstr /i "Hyper-V" | findstr /i "Yes" >nul
if !errorlevel! equ 0 (
echo [PASS] Hyper-V capable
) else (
echo [FAIL] Hyper-V not detected
echo [INFO] Enable virtualization in BIOS/UEFI
)
echo.
:: ============================================================
:: Overall Assessment
:: ============================================================
echo ============================================================
echo Overall Assessment
echo ============================================================
echo.
if !PSResult! equ 0 (
echo [PASS] Credential Guard is FULLY OPERATIONAL
echo.
echo - Registry configuration: !RegStatus!
echo - Runtime status: Active
echo - VBS: Running
echo.
echo System is properly protected.
set "ExitCode=0"
) else if !PSResult! equ 1 (
echo [WARN] Credential Guard is CONFIGURED but not running
echo.
echo - Registry configuration: !RegStatus!
echo - Configured but inactive
echo.
echo Action Required:
echo - Reboot the system to activate
echo - Check UEFI virtualization settings
set "ExitCode=1"
) else if !PSResult! equ 2 (
echo [FAIL] Credential Guard is NOT CONFIGURED
echo.
echo - Registry configuration: !RegStatus!
echo - Not active
echo.
echo To enable Credential Guard:
echo 1. Ensure UEFI firmware
echo 2. Enable virtualization in BIOS
echo 3. Configure via Group Policy or Registry
echo 4. Reboot system
set "ExitCode=2"
) else (
echo [FAIL] Unable to determine Credential Guard status
echo.
echo - WMI query failed
echo - System may not support Credential Guard
echo - Check Windows edition and hardware requirements
set "ExitCode=3"
)
echo.
echo ============================================================
echo.
pause
endlocal
exit /b %ExitCode%Common Pitfalls and How to Avoid Them
Configured vs. Running
A script might show LsaCfgFlags as 1, but Credential Guard could still be inactive if "Secure Boot" is disabled in the BIOS.
Wrong Way:
:: Only checking the registry keyCorrect Way: Always use Method 2 (WMI) to verify that the service is actually "Running". If it's configured in the registry but not running in WMI, your script should alert the user to check their BIOS/UEFI settings.
Edition Mismatch
Credential Guard is often officially restricted to Enterprise and Education editions.
Best Practices for Identity Protection
- Enable UEFI Lock: Use
LsaCfgFlags = 1for maximum security. This prevents an attacker with physical access from disabling Credential Guard via simple registry edits. - Verify Secure Boot: Use
powershell -NoProfile -Command "Confirm-SecureBootUEFI"to ensure the foundation of Credential Guard is active. - Check Hardware Compatibility: Use the official "Device Guard and Credential Guard Hardware Readiness Tool" if your Batch script detects persistent launch failures.
Conclusion
Checking if Credential Guard is enabled via Batch script is a critical task for maintaining a high-security posture in modern Windows environments. By utilizing both registry queries and deep-level WMI audits, you can ensure that your users' and administrators' credentials are protected by the full power of virtualization-based security. This professional approach to system identification maintains the integrity of your organization's identities, providing a clear, automated view of your defense status and ensuring your infrastructure remains resilient against advanced credential-harvesting attacks.