With Windows 10 end of support behind us (October 14, 2025), TPM 2.0 queries have become one of the most common pre-migration health checks in enterprise IT. Whether you are running a Windows 11 eligibility audit, configuring Intune compliance policies, troubleshooting Autopilot attestation, or preparing for BitLocker deployment, this guide covers every method to query TPM status, version, and health via PowerShell — including fleet-wide approaches via Intune Remediation and SCCM.
| Detail | |
|---|---|
| Last Updated | March 2026 |
| Applies To | Windows 10, Windows 11, Windows Server 2019/2022/2025 |
| Windows 11 Requirement | TPM 2.0 (firmware or discrete), enabled and activated |
| Requires Admin | Get-Tpm: Yes. tpmtool: No. CIM: No. |
| Difficulty | Beginner |
Method 1: Get-Tpm Cmdlet (Simplest)
The built-in Get-Tpm cmdlet from the TrustedPlatformModule module is the quickest way to check TPM status. It requires an elevated PowerShell session (Run as Administrator):
# Basic TPM status — requires elevation
Get-Tpm
Sample output on a healthy Windows 11 device:
TpmPresent : True
TpmReady : True
TpmEnabled : True
TpmActivated : True
TpmOwned : True
RestartPending : False
ManufacturerIdTxt : INTC
ManufacturerVersion : 302.12.0.0
ManufacturerVersionFull20 : 302.12.0.0
ManagedAuthLevel : Full
OwnerAuth :
OwnerClearDisabled : True
AutoProvisioning : Enabled
LockedOut : False
LockoutHealTime : 10 minutes
CurrentPcrBanks : {Sha1, Sha256}
AvailablePcrBanks : {Sha1, Sha256}
LockoutCount : 0
For Windows 11 eligibility, the critical properties are TpmPresent, TpmEnabled, TpmActivated, and TpmReady — all four must be True. TpmReady specifically indicates the TPM is fully provisioned and ready for use by the OS.
Method 2: Get TPM Version via CIM (No Elevation Required)
For scripts that run without elevation — such as Intune Remediation detection scripts running as user context — use the CIM-based approach:
# Get TPM version via CIM — no elevation required
$tpm = Get-CimInstance -Namespace "root\cimv2\Security\MicrosoftTpm" -ClassName "Win32_Tpm"
if ($tpm) {
# SpecVersion returns e.g. "2.0, 1.16, 8" — take the highest version number
$specVersion = ($tpm.SpecVersion -split ", " | Sort-Object | Select-Object -Last 1)
[PSCustomObject]@{
TPMPresent = $true
SpecVersion = $specVersion
ManufacturerVersion = $tpm.ManufacturerVersion
IsEnabled = $tpm.IsEnabled_InitialValue
IsActivated = $tpm.IsActivated_InitialValue
IsOwned = $tpm.IsOwned_InitialValue
}
} else {
Write-Host "No TPM found — device may not have a TPM or it is disabled in BIOS."
}
Method 3: tpmtool — Detailed Info Without Elevation
tpmtool.exe is a built-in Windows command-line tool that returns detailed TPM diagnostics including attestation readiness — useful for Autopilot troubleshooting. It does not require elevation:
# Full TPM device information
tpmtool getdeviceinformation
# Collect full TPM logs to a folder (useful for support escalation)
tpmtool gatherlogs "$env:USERPROFILE\Desktop\TPMLogs"
The getdeviceinformation output includes fields that Get-Tpm does not expose — notably Ready For Attestation, Is Capable For Attestation, and TPM Has Vulnerable Firmware. Parse it into a PowerShell object:
# Parse tpmtool output into a structured PowerShell object
$tpmToolOutput = tpmtool getdeviceinformation
$tpmInfo = @{}
foreach ($line in $tpmToolOutput) {
if ($line -match "^-(.+?):\s+(.+)$") {
$key = $matches[1].Trim() -replace " ", "_"
$value = $matches[2].Trim()
$tpmInfo[$key] = $value
}
}
[PSCustomObject]$tpmInfo | Format-List
Complete TPM Health Report
A combined script that pulls data from both Get-Tpm and CIM — useful as a single-device health check or the basis for a fleet audit:
# Comprehensive TPM health report
# Requires elevation for Get-Tpm; CIM section works without elevation
function Get-TPMHealthReport {
$report = [ordered]@{ ComputerName = $env:COMPUTERNAME }
# CIM section — no elevation needed
try {
$cimTpm = Get-CimInstance -Namespace "root\cimv2\Security\MicrosoftTpm" `
-ClassName "Win32_Tpm" -ErrorAction Stop
$specVersion = ($cimTpm.SpecVersion -split ", " |
Sort-Object | Select-Object -Last 1)
$report["TPM_Present"] = $true
$report["TPM_SpecVersion"] = $specVersion
$report["TPM_Is2_0"] = ($specVersion -ge "2.0")
$report["TPM_ManufacturerVersion"] = $cimTpm.ManufacturerVersion
$report["TPM_Enabled"] = $cimTpm.IsEnabled_InitialValue
$report["TPM_Activated"] = $cimTpm.IsActivated_InitialValue
$report["TPM_Owned"] = $cimTpm.IsOwned_InitialValue
} catch {
$report["TPM_Present"] = $false
$report["TPM_SpecVersion"] = "Not found"
}
# Get-Tpm section — requires elevation
try {
$getTpm = Get-Tpm -ErrorAction Stop
$report["TPM_Ready"] = $getTpm.TpmReady
$report["TPM_LockedOut"] = $getTpm.LockedOut
$report["TPM_AutoProvisioning"] = $getTpm.AutoProvisioning
$report["TPM_ManufacturerId"] = $getTpm.ManufacturerIdTxt
$report["PCR_Banks"] = ($getTpm.CurrentPcrBanks -join ", ")
} catch {
$report["TPM_Ready"] = "Elevation required"
}
# Secure Boot status
try {
$report["SecureBoot_Enabled"] = (Confirm-SecureBootUEFI -ErrorAction Stop)
} catch {
$report["SecureBoot_Enabled"] = "Not supported or legacy BIOS"
}
# Windows 11 eligibility summary
$w11Eligible = ($report["TPM_Is2_0"] -eq $true) -and
($report["TPM_Enabled"] -eq $true) -and
($report["TPM_Activated"] -eq $true)
$report["Windows11_TPM_Eligible"] = $w11Eligible
[PSCustomObject]$report
}
Get-TPMHealthReport | Format-List
Fleet Audit: Windows 11 TPM Eligibility via Intune Remediation
Use this as a detection-only Intune Remediation to identify devices in your fleet that do not meet the Windows 11 TPM requirement. The results appear in the Intune Remediations reporting dashboard:
# Detection script: Is device TPM 2.0 eligible for Windows 11?
# Deploy as detection-only Intune Remediation (no remediation script needed)
# Exit 0 = compliant (TPM 2.0 present and enabled)
# Exit 1 = non-compliant (TPM missing, disabled, or version 1.2)
try {
$tpm = Get-CimInstance -Namespace "root\cimv2\Security\MicrosoftTpm" `
-ClassName "Win32_Tpm" -ErrorAction Stop
if (-not $tpm) {
Write-Host "Non-compliant: No TPM found"
exit 1
}
$specVersion = ($tpm.SpecVersion -split ", " | Sort-Object | Select-Object -Last 1)
if ([version]$specVersion -lt [version]"2.0") {
Write-Host "Non-compliant: TPM version $specVersion — Windows 11 requires 2.0"
exit 1
}
if (-not $tpm.IsEnabled_InitialValue) {
Write-Host "Non-compliant: TPM $specVersion present but disabled in BIOS"
exit 1
}
if (-not $tpm.IsActivated_InitialValue) {
Write-Host "Non-compliant: TPM $specVersion present but not activated"
exit 1
}
Write-Host "Compliant: TPM $specVersion — enabled and activated"
exit 0
} catch {
Write-Host "Error querying TPM: $_"
exit 1
}
Bulk Fleet Query via Invoke-Command
Query TPM status across multiple remote devices in parallel using PSRemoting:
# Query TPM status across multiple remote machines
$computers = @("PC001", "PC002", "PC003", "SERVER01")
$results = Invoke-Command -ComputerName $computers -ScriptBlock {
$tpm = Get-CimInstance -Namespace "root\cimv2\Security\MicrosoftTpm" `
-ClassName "Win32_Tpm" -ErrorAction SilentlyContinue
if (-not $tpm) {
return [PSCustomObject]@{
Computer = $env:COMPUTERNAME
TPMPresent = $false
Version = "None"
Enabled = $false
W11Ready = $false
}
}
$version = ($tpm.SpecVersion -split ", " | Sort-Object | Select-Object -Last 1)
[PSCustomObject]@{
Computer = $env:COMPUTERNAME
TPMPresent = $true
Version = $version
Enabled = $tpm.IsEnabled_InitialValue
Activated = $tpm.IsActivated_InitialValue
W11Ready = ($version -ge "2.0" -and $tpm.IsEnabled_InitialValue)
}
} -ErrorAction SilentlyContinue
$results | Sort-Object W11Ready, Computer |
Select-Object Computer, TPMPresent, Version, Enabled, Activated, W11Ready |
Format-Table -AutoSize
# Export to CSV for management reporting
$results | Export-Csv "C:\Temp\TPM_Fleet_Audit.csv" -NoTypeInformation
Write-Host "Exported to C:\Temp\TPM_Fleet_Audit.csv"
Check TPM Attestation Readiness (Autopilot / Windows Hello for Business)
For Autopilot deployments and Windows Hello for Business, the TPM must not only be present and enabled but also attestation-capable. Virtual TPMs and some older discrete TPMs are blocked from attestation by Microsoft:
# Check TPM attestation readiness
$tpmTool = tpmtool getdeviceinformation
$attestReady = ($tpmTool | Select-String "Ready For Attestation").ToString() -match "True"
$attestCapable = ($tpmTool | Select-String "Is Capable For Attestation").ToString() -match "True"
$vulnFirmware = ($tpmTool | Select-String "TPM Has Vulnerable Firmware").ToString() -match "True"
$clearNeeded = ($tpmTool | Select-String "Clear Needed To Recover").ToString() -match "True"
[PSCustomObject]@{
ComputerName = $env:COMPUTERNAME
ReadyForAttestation = $attestReady
CapableForAttestation = $attestCapable
VulnerableFirmware = $vulnFirmware
ClearNeededToRecover = $clearNeeded
AttestationStatus = if ($attestReady) { "OK" }
elseif (-not $attestCapable) { "Not capable — virtual TPM or blocklisted" }
elseif ($vulnFirmware) { "Blocked — vulnerable firmware" }
elseif ($clearNeeded) { "TPM clear required" }
else { "Not ready — check tpmtool output" }
} | Format-List
Common TPM Issues and Fixes
| Issue | Cause | Fix |
|---|---|---|
| TpmPresent = False | TPM disabled in BIOS/UEFI | Enable TPM in BIOS — look for Intel PTT, AMD fTPM, or dedicated TPM setting |
| TpmReady = False but TpmPresent = True | TPM not provisioned or owned | Run: Initialize-Tpm -AllowClear — or clear TPM in BIOS and let Windows reprovision |
| TPM version 1.2 on device | Older hardware without firmware TPM 2.0 | Check BIOS for firmware upgrade; some older Intel devices can update from PTT 1.2 to 2.0 |
| Ready For Attestation: False | Virtual TPM, vulnerable firmware, or blocklisted chip | Virtual TPMs cannot attest. For vulnerable firmware, update TPM firmware from the OEM |
| TPM LockedOut = True | Too many failed authorization attempts | Wait for lockout to heal (shown in LockoutHealTime); or clear TPM in BIOS |
| Get-Tpm returns error 0x80280400 | TPM Base Services not running | Start service: Start-Service -Name “TPM Base Services” |
Summary
TPM querying in PowerShell is more relevant in 2026 than ever — Windows 11 eligibility audits, Autopilot attestation troubleshooting, and BitLocker compliance checks all depend on accurate TPM status data. Use the CIM method for non-elevated or Intune Remediation contexts, Get-Tpm for elevated single-device checks, and tpmtool for attestation diagnostics.
- Use
Get-CimInstance -Namespace "root\cimv2\Security\MicrosoftTpm" -ClassName "Win32_Tpm"for non-elevated scripts and fleet audits - Use
Get-Tpm(elevated) for full status includingTpmReady, lockout state, and PCR banks - Use
tpmtool getdeviceinformationfor attestation readiness — essential for Autopilot and Windows Hello for Business troubleshooting - Deploy the Intune Remediation detection script as a fleet audit to identify Windows 11-ineligible devices before migrating
- Virtual TPMs (Hyper-V, Azure VMs) cannot attest — this is by design and not fixable
