How to Get TPM Version Information in Batch Script
The Trusted Platform Module (TPM) is a hardware security chip embedded in most modern computers. It provides cryptographic functions for disk encryption (BitLocker), secure boot, credential storage, and device attestation. Since Windows 11 requires TPM 2.0 as a hard prerequisite, knowing which TPM version is installed has become a critical system check. Retrieving TPM version information from a Batch Script enables automated compatibility assessments, security audits, and upgrade readiness reporting across machine fleets.
In this guide, we will explore how to retrieve TPM version information from a Batch Script using WMI, PowerShell, the registry, and the built-in tpm.msc snap-in.
Understanding TPM Versions
| Version | Description |
|---|---|
| TPM 1.2 | Legacy standard. Supports SHA-1. Used in Windows 7/8/10 era. |
| TPM 2.0 | Current standard. Supports SHA-256. Required for Windows 11. |
| Not present | Some virtual machines and older hardware lack a TPM entirely. |
TPM 2.0 is required for Windows 11, BitLocker automatic device encryption, and Windows Hello for Business. Checking the TPM version is a key step in Windows 11 upgrade readiness assessments.
Method 1: Using WMIC
The WMI class Win32_Tpm in the root\cimv2\Security\MicrosoftTpm namespace provides TPM details:
@echo off
setlocal EnableDelayedExpansion
echo =============================================
echo TPM VERSION CHECK
echo =============================================
echo.
:: Check for admin (required for TPM WMI queries)
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] This script must be run as Administrator.
echo TPM queries require elevated privileges.
pause
exit /b 1
)
:: Query TPM version
set "TPM_SPEC="
for /f "tokens=2 delims==" %%a in ('wmic /namespace:\\root\cimv2\Security\MicrosoftTpm path Win32_Tpm get SpecVersion /value 2^>nul ^| findstr "="') do (
for /f "delims=" %%b in ("%%a") do set "TPM_SPEC=%%b"
)
if defined TPM_SPEC (
echo TPM Spec Version: !TPM_SPEC!
echo !TPM_SPEC! | findstr /c:"2.0" >nul
if !errorlevel! equ 0 (
echo [OK] TPM 2.0 detected. Windows 11 compatible.
) else (
echo !TPM_SPEC! | findstr /c:"1.2" >nul
if !errorlevel! equ 0 (
echo [WARNING] TPM 1.2 detected. Not compatible with Windows 11.
) else (
echo TPM version: !TPM_SPEC!
)
)
) else (
echo [NOT FOUND] No TPM detected on this system.
echo [HELP] Check BIOS for 'TPM', 'PTT' (Intel^), or 'fTPM' (AMD^).
)
pause
Method 2: Detailed TPM Report via WMIC
Retrieve all available TPM properties:
@echo off
setlocal EnableDelayedExpansion
echo =============================================
echo DETAILED TPM REPORT
echo %COMPUTERNAME% - %date%
echo =============================================
echo.
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Run as Administrator.
pause
exit /b 1
)
set "NS=\\root\cimv2\Security\MicrosoftTpm"
:: Check if TPM exists
wmic /namespace:%NS% path Win32_Tpm get IsActivated_InitialValue /value >nul 2>&1
if %errorlevel% neq 0 (
echo [NOT FOUND] No TPM hardware detected.
echo [HELP] Check BIOS for TPM, PTT (Intel^), or fTPM (AMD^).
pause
exit /b 1
)
:: Spec Version
set "SPEC="
for /f "tokens=2 delims==" %%a in ('wmic /namespace:%NS% path Win32_Tpm get SpecVersion /value 2^>nul ^| findstr "="') do (
for /f "delims=" %%b in ("%%a") do set "SPEC=%%b"
)
if "!SPEC!"=="" set "SPEC=Not Available"
:: Manufacturer Version
set "MFG_VER="
for /f "tokens=2 delims==" %%a in ('wmic /namespace:%NS% path Win32_Tpm get ManufacturerVersion /value 2^>nul ^| findstr "="') do (
for /f "delims=" %%b in ("%%a") do set "MFG_VER=%%b"
)
if "!MFG_VER!"=="" set "MFG_VER=Not Available"
:: Manufacturer ID
set "MFG_ID="
for /f "tokens=2 delims==" %%a in ('wmic /namespace:%NS% path Win32_Tpm get ManufacturerIdTxt /value 2^>nul ^| findstr "="') do (
for /f "delims=" %%b in ("%%a") do set "MFG_ID=%%b"
)
if "!MFG_ID!"=="" set "MFG_ID=Not Available"
:: Is Activated
set "ACTIVATED="
for /f "tokens=2 delims==" %%a in ('wmic /namespace:%NS% path Win32_Tpm get IsActivated_InitialValue /value 2^>nul ^| findstr "="') do (
for /f "delims=" %%b in ("%%a") do set "ACTIVATED=%%b"
)
if "!ACTIVATED!"=="" (
set "ACTIVATED=Unknown"
) else if "!ACTIVATED!"=="True" (
set "ACTIVATED=Yes"
) else (
set "ACTIVATED=No"
)
:: Is Enabled
set "ENABLED="
for /f "tokens=2 delims==" %%a in ('wmic /namespace:%NS% path Win32_Tpm get IsEnabled_InitialValue /value 2^>nul ^| findstr "="') do (
for /f "delims=" %%b in ("%%a") do set "ENABLED=%%b"
)
if "!ENABLED!"=="" (
set "ENABLED=Unknown"
) else if "!ENABLED!"=="True" (
set "ENABLED=Yes"
) else (
set "ENABLED=No"
)
:: Is Owned
set "OWNED="
for /f "tokens=2 delims==" %%a in ('wmic /namespace:%NS% path Win32_Tpm get IsOwned_InitialValue /value 2^>nul ^| findstr "="') do (
for /f "delims=" %%b in ("%%a") do set "OWNED=%%b"
)
if "!OWNED!"=="" (
set "OWNED=Unknown"
) else if "!OWNED!"=="True" (
set "OWNED=Yes"
) else (
set "OWNED=No"
)
:: Physical Presence (additional check)
set "PHYS_PRES="
for /f "tokens=2 delims==" %%a in ('wmic /namespace:%NS% path Win32_Tpm get PhysicalPresenceVersion /value 2^>nul ^| findstr "="') do (
for /f "delims=" %%b in ("%%a") do set "PHYS_PRES=%%b"
)
if "!PHYS_PRES!"=="" set "PHYS_PRES=Not Available"
echo Spec Version: !SPEC!
echo Manufacturer: !MFG_ID!
echo Manufacturer Version: !MFG_VER!
echo Activated: !ACTIVATED!
echo Enabled: !ENABLED!
echo Owned: !OWNED!
echo Physical Presence: !PHYS_PRES!
echo.
:: Windows 11 compatibility assessment
if "!SPEC!"=="Not Available" (
echo [UNKNOWN] Cannot determine TPM version.
) else (
echo !SPEC! | findstr /c:"2.0" >nul
if !errorlevel! equ 0 (
echo [COMPATIBLE] TPM 2.0 meets Windows 11 requirements.
) else (
echo [INCOMPATIBLE] TPM version !SPEC! does not meet Windows 11 requirements.
)
)
echo.
pause
Method 3: PowerShell-Based TPM Query
PowerShell provides the Get-Tpm cmdlet and access to the full WMI class:
@echo off
echo Retrieving TPM information via PowerShell...
echo.
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Run as Administrator.
pause
exit /b 1
)
powershell -NoProfile -Command ^
"$tpm = Get-CimInstance -Namespace 'root\cimv2\Security\MicrosoftTpm' -ClassName Win32_Tpm -ErrorAction SilentlyContinue;" ^
"if ($tpm) {" ^
" $spec = $tpm.SpecVersion;" ^
" Write-Host ('TPM Spec Version: ' + $spec);" ^
" Write-Host ('Manufacturer: ' + $tpm.ManufacturerIdTxt);" ^
" Write-Host ('Manufacturer Version: ' + $tpm.ManufacturerVersion);" ^
" Write-Host ('Activated: ' + $tpm.IsActivated_InitialValue);" ^
" Write-Host ('Enabled: ' + $tpm.IsEnabled_InitialValue);" ^
" Write-Host ('Owned: ' + $tpm.IsOwned_InitialValue);" ^
" Write-Host '';" ^
" if ($spec -match '2\.0') {" ^
" Write-Host '[OK] TPM 2.0 - Windows 11 compatible.'" ^
" } elseif ($spec -match '1\.2') {" ^
" Write-Host '[WARNING] TPM 1.2 - Not compatible with Windows 11.'" ^
" }" ^
"} else {" ^
" Write-Host '[NOT FOUND] No TPM detected.';" ^
" Write-Host '[HELP] Check BIOS for TPM, PTT (Intel), or fTPM (AMD).'" ^
"}" 2>nul
pause
For a simpler check using the built-in Get-Tpm cmdlet:
@echo off
echo Quick TPM status:
echo.
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Run as Administrator.
pause
exit /b 1
)
powershell -NoProfile -Command ^
"$t = Get-Tpm -ErrorAction SilentlyContinue;" ^
"if ($t) {" ^
" Write-Host ('Present: ' + $t.TpmPresent);" ^
" Write-Host ('Ready: ' + $t.TpmReady);" ^
" Write-Host ('Enabled: ' + $t.TpmEnabled);" ^
" Write-Host ('Activated: ' + $t.TpmActivated);" ^
" Write-Host ('Owned: ' + $t.TpmOwned)" ^
"} else {" ^
" Write-Host 'TPM information unavailable. Run as Administrator.'" ^
"}" 2>nul
pause
Method 4: Registry-Based Check
Some TPM information is cached in the registry:
@echo off
setlocal
echo Checking TPM via registry...
echo.
set "KEY=HKLM\SYSTEM\CurrentControlSet\Services\TPM"
reg query "%KEY%" >nul 2>&1
if %errorlevel% neq 0 (
echo [NOT FOUND] TPM service registry key does not exist.
pause
exit /b 1
)
:: TPM driver info
for /f "tokens=2,*" %%a in ('reg query "%KEY%" /v ImagePath 2^>nul ^| findstr /i "ImagePath"') do echo TPM Driver: %%b
for /f "tokens=3" %%a in ('reg query "%KEY%" /v Start 2^>nul ^| findstr /i "Start"') do echo Start Type: %%a
:: Additional TPM data from hardware key
set "HW_KEY=HKLM\HARDWARE\DESCRIPTION\System\TPM"
for /f "tokens=3" %%a in ('reg query "%HW_KEY%" /v ManufacturerId 2^>nul ^| findstr /i "ManufacturerId"') do echo Manufacturer ID: %%a
echo.
echo [NOTE] For full TPM version details, use Method 1 or 3 (requires elevation^).
pause
Method 5: Windows 11 Readiness Check
Combine TPM with other Windows 11 requirements:
@echo off
setlocal EnableDelayedExpansion
echo =============================================
echo WINDOWS 11 READINESS CHECK
echo =============================================
echo.
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Run as Administrator for full check.
pause
exit /b 1
)
set "pass=0"
set "fail=0"
:: Check 1: TPM 2.0
echo [1/4] TPM 2.0...
set "TPM="
for /f "tokens=2 delims==" %%a in ('wmic /namespace:\\root\cimv2\Security\MicrosoftTpm path Win32_Tpm get SpecVersion /value 2^>nul ^| findstr "="') do (
for /f "delims=" %%b in ("%%a") do set "TPM=%%b"
)
if defined TPM (
echo "!TPM!" | findstr /c:"2.0" >nul
if !errorlevel! equ 0 (
echo [PASS] TPM 2.0 detected.
set /a "pass+=1"
) else (
:: wmic appends a hidden carriage return \r. To prevent line overwrite
:: bugs in the console output, we strip the last character safely:
set "CleanTPM=!TPM:~0,-1!"
echo [FAIL] TPM !CleanTPM! (need 2.0^)
set /a "fail+=1"
)
) else (
echo [FAIL] No TPM detected.
set /a "fail+=1"
)
:: Check 2: Secure Boot
echo [2/4] Secure Boot...
set "SB_RESULT="
for /f "usebackq tokens=*" %%r in (`powershell -NoProfile -Command "try { Confirm-SecureBootUEFI -ErrorAction Stop } catch { Write-Output 'UNSUPPORTED' }" 2^>nul`) do set "SB_RESULT=%%r"
if /i "!SB_RESULT!"=="True" (
echo [PASS] Secure Boot enabled.
set /a "pass+=1"
) else (
echo [FAIL] Secure Boot not enabled or not supported.
set /a "fail+=1"
)
:: Check 3: RAM (4 GB minimum)
echo [3/4] RAM...
set "RAM_BYTES="
for /f "tokens=2 delims==" %%m in ('wmic computersystem get TotalPhysicalMemory /value 2^>nul ^| findstr "="') do (
for /f "delims=" %%n in ("%%m") do set "RAM_BYTES=%%n"
)
if defined RAM_BYTES (
:: Use $env to safely pass the value to PowerShell. PS naturally ignores the hidden \r
powershell -NoProfile -Command "if ([math]::Round($env:RAM_BYTES / 1GB) -ge 4) { exit 0 } else { exit 1 }" >nul 2>&1
if !errorlevel! equ 0 (
echo [PASS] Sufficient RAM.
set /a "pass+=1"
) else (
echo [FAIL] Less than 4 GB RAM.
set /a "fail+=1"
)
) else (
echo [FAIL] Could not determine RAM.
set /a "fail+=1"
)
:: Check 4: UEFI firmware
echo [4/4] UEFI Firmware...
bcdedit /enum {current} 2>nul | findstr /i /c:"winload.efi" >nul
if !errorlevel! equ 0 (
echo [PASS] UEFI firmware detected.
set /a "pass+=1"
) else (
echo [FAIL] Legacy BIOS (UEFI required^).
set /a "fail+=1"
)
echo.
echo =============================================
echo RESULT: !pass! passed, !fail! failed
if !fail! equ 0 (
echo [COMPATIBLE] This PC meets Windows 11 requirements.
) else (
echo [INCOMPATIBLE] This PC does not meet all requirements.
)
echo =============================================
pause
Opening the TPM Management Console
For quick manual inspection:
@echo off
echo Opening TPM Management Console...
tpm.msc
Common Mistakes
The Wrong Way: Running Without Elevation
:: WRONG - TPM WMI queries require administrator privileges
wmic /namespace:\\root\cimv2\Security\MicrosoftTpm path Win32_Tpm get SpecVersion
:: Returns empty or "Access denied"
Output Concern:
The Win32_Tpm WMI class is in a security namespace that requires administrator privileges. Always run TPM query scripts with "Run as Administrator" or the results will be empty or return an access error.
The Wrong Way: Assuming TPM Exists
:: WRONG - No check before using TPM data
for /f ... in ('wmic ... Win32_Tpm get SpecVersion') do set "VER=%%a"
echo TPM version is %VER%
:: If no TPM exists, VER is empty and the message is misleading
Always check whether the WMI query returned data before displaying results. Use if defined to verify the variable was actually set.
Best Practices
- Run elevated: TPM WMI queries require administrator privileges without exception.
- Check for TPM presence first: Not all machines have a TPM, especially virtual machines.
- Parse the SpecVersion string: It contains the major version (e.g., "2.0") needed for compatibility checks.
- Combine with other checks: TPM version alone is not sufficient for Windows 11 readiness. Include Secure Boot, RAM, and UEFI checks.
- Log the manufacturer: Different TPM manufacturers (Intel, AMD, Infineon) may have firmware update requirements.
Conclusion
Retrieving TPM version information from a Batch Script is accomplished through WMI queries against the Win32_Tpm class in the root\cimv2\Security\MicrosoftTpm namespace. The key property is SpecVersion, which indicates whether the chip is TPM 1.2 or 2.0. By combining TPM version checks with other system assessments like Secure Boot and UEFI firmware status, administrators build comprehensive Windows 11 readiness reports that identify exactly which machines in their environment are ready for upgrade and which require hardware or firmware changes.