Tests the Windows 11 hardware requirements — TPM, Secure Boot, processor, memory and system disk — and writes a formatted HTML report to the desktop, or to a file share once you change the output path. The long part of this script is the report template; the checks themselves are near the bottom.
powershell
# Windows 11 Compatibility Check
# This script checks Windows 11 compatibility and generates
# an HTML report on the desktop, you can change the location
# to fileshare, see line 768
#---------------------------------------------------------------
# Windows 11 Compatibility Check Script with HTML Report
# This script checks Windows 11 compatibility and generates an HTML report on the desktop
# Function to create HTML report
function New-HTMLReport {
param(
[hashtable]$Results,
[hashtable]$SystemInfo,
[int]$Passed,
[int]$Total
)
$html = @"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Windows 11 Compatibility Report</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: #2c3e50;
line-height: 1.6;
padding: 20px;
min-height: 100vh;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
.header {
background: white;
border-radius: 15px;
padding: 30px;
text-align: center;
margin-bottom: 30px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}
h1 {
color: #2c3e50;
margin-bottom: 10px;
font-size: 2.5em;
}
.subtitle {
color: #7f8c8d;
font-size: 1.2em;
}
.summary {
background: white;
border-radius: 15px;
padding: 25px;
margin-bottom: 30px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}
.summary-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin-top: 20px;
}
.summary-item {
text-align: center;
padding: 20px;
border-radius: 10px;
background: #f8f9fa;
}
.summary-value {
font-size: 2.5em;
font-weight: bold;
margin-bottom: 5px;
}
tesetgn: center;
padding: 20px;
border-radius: 10px;
background: #f8f9fa;
}
.summary-value {
font-size: 2.5em;
font-weight: bold;
margin-bottom: 5px;
}
tesetgn: center;
padding: 20px;
border-radius: 10px;
background: #f8f9fa;
}
.summary-value {
font-size: 2.5em;
font-weight: bold;
margin-bottom: 5px;
}
.summary-label {
color: #7f8c8d;
font-size: 0.9em;
}
.checks-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.check-card {
background: white;
border-radius: 15px;
padding: 25px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
transition: transform 0.3s ease;
}
.check-card:hover {
transform: translateY(-5px);
}
.check-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
}
.check-title {
font-size: 1.2em;
font-weight: bold;
color: #2c3e50;
}
.status-badge {
padding: 6px 15px;
border-radius: 20px;
font-weight: bold;
font-size: 0.9em;
}
.status-pass {
background: #d4edda;
color: #155724;
}
.status-fail {
background: #f8d7da;
color: #721c24;
}
.status-warning {
background: #fff3cd;
color: #856404;
}
.check-details {
color: #7f8c8d;
font-size: 0.95em;
line-height: 1.5;
}
.system-info {
background: white;
border-radius: 15px;
padding: 25px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}
.info-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 15px;
margin-top: 15px;
}
.info-item {
padding: 10px;
border-bottom: 1px solid #ecf0f1;
}
.info-label {
font-weight: bold;
color: #2c3e50;
}
.info-value {
color: #7f8c8d;
}
.footer {
text-align: center;
margin-top: 30px;
color: white;
font-size: 0.9em;
}
.progress-bar {
height: 10px;
background: #ecf0f1;
border-radius: 5px;
margin: 20px 0;
overflow: hidden;
}
.progress-fill {
height: 100%;
border-radius: 5px;
transition: width 0.5s ease;
}
.progress-pass {
background: linear-gradient(90deg, #28a745, #20c997);
}
.progress-warning {
background: linear-gradient(90deg, #ffc107, #fd7e14);
}
.recommendation {
background: #e3f2fd;
border-left: 4px solid #2196f3;
padding: 15px;
margin-top: 15px;
border-radius: 0 8px 8px 0;
}
@media (max-width: 768px) {
.checks-grid {
grid-template-columns: 1fr;
}
.summary-grid {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Windows 11 Compatibility Report</h1>
<p class="subtitle">Generated on $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")</p>
</div>
<div class="summary">
<h2>Compatibility Summary</h2>
<div class="progress-bar">
<div class="progress-fill $(if ($Passed -eq $Total) { 'progress-pass' } else { 'progress-warning' })" style="width: $(($Passed/$Total)*100)%"></div>
</div>
<div class="summary-grid">
<div class="summary-item">
<div class="summary-value" style="color: #28a745;">$Passed</div>
<div class="summary-label">Requirements Passed</div>
</div>
<div class="summary-item">
<div class="summary-value" style="color: #dc3545;">$($Total - $Passed)</div>
<div class="summary-label">Requirements Failed</div>
</div>
<div class="summary-item">
<div class="summary-value" style="color: #007bff;">$Total</div>
<div class="summary-label">Total Checks</div>
</div>
<div class="summary-item">
<div class="summary-value" style="color: #6c757d;">$([math]::Round(($Passed/$Total)*100, 1))%</div>
<div class="summary-label">Compatibility Score</div>
</div>
</div>
"@
# Add overall recommendation
if ($Passed -eq $Total) {
$html += @"
<div class="recommendation">
<strong>🎉 Excellent!</strong> Your device appears to meet all Windows 11 requirements. You should be able to upgrade without issues.
</div>
"@
} elseif ($Passed -ge ($Total * 0.7)) {
$html += @"
<div class="recommendation">
<strong>⚠️ Good Compatibility</strong> Your device meets most Windows 11 requirements. Some features may require hardware updates.
</div>
"@
} else {
$html += @"
<div class="recommendation">
<strong>❌ Limited Compatibility</strong> Your device may not be eligible for Windows 11. Consider hardware upgrades or check with your manufacturer.
</div>
"@
}
$html += @"
</div>
<div class="checks-grid">
"@
# Add check cards
foreach ($check in $Results.GetEnumerator()) {
$statusClass = if ($check.Value.Passed) { "status-pass" } else { "status-fail" }
$statusText = if ($check.Value.Passed) { "PASS" } else { "FAIL" }
$html += @"
<div class="check-card">
<div class="check-header">
<div class="check-title">$($check.Value.Name)</div>
<div class="status-badge $statusClass">$statusText</div>
</div>
<div class="check-details">
$($check.Value.Details -join "<br>")
</div>
</div>
"@
}
$html += @"
</div>
<div class="system-info">
<h2>System Information</h2>
<div class="info-grid">
"@
# Add system information
foreach ($info in $SystemInfo.GetEnumerator()) {
$html += @"
<div class="info-item">
<div class="info-label">$($info.Key):</div>
<div class="info-value">$($info.Value)</div>
</div>
"@
}
$html += @"
</div>
</div>
<div class="footer">
<p>Report generated by Windows 11 Compatibility Checker</p>
<p>For more information, visit: <a href="https://www.microsoft.com/en-us/windows/windows-11-specifications" style="color: white;">Microsoft Windows 11 Specifications</a></p>
</div>
</div>
</body>
</html>
"@
return $html
}
# Enhanced UEFI Check Function
function Test-UEFI {
try {
$details = @()
$detectionMethod = ""
# Method 1: Check via firmware type (works on Windows 8/Server 2012 and newer)
$firmwareType = Get-CimInstance -ClassName Win32_ComputerSystem | Select-Object -ExpandProperty PCSystemType
if ($firmwareType -eq 2) {
$details += "UEFI firmware detected (PCSystemType method)"
$detectionMethod = "Firmware Type"
return @{Passed = $true; Details = $details; Method = $detectionMethod}
}
# Method 2: Check Secure Boot status (indicates UEFI)
$secureBoot = Get-CimInstance -Namespace "Root\StandardCimv2" -ClassName MSFT_SecureBoot -ErrorAction SilentlyContinue
if ($secureBoot -and $secureBoot.SecureBootEnabled) {
$details += "UEFI detected via Secure Boot status"
$detectionMethod = "Secure Boot"
return @{Passed = $true; Details = $details; Method = $detectionMethod}
}
# Method 3: Check via BIOS/firmware class
$bios = Get-CimInstance -ClassName Win32_BIOS
if ($bios.BIOSVersion -like "*UEFI*" -or $bios.Name -like "*UEFI*") {
$details += "UEFI detected in BIOS information"
$detectionMethod = "BIOS Information"
return @{Passed = $true; Details = $details; Method = $detectionMethod}
}
# Method 4: Check registry (for older systems)
$registryUEFI = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\State" -Name "UEFISecureBootEnabled" -ErrorAction SilentlyContinue
if ($registryUEFI -ne $null) {
$details += "UEFI detected via registry method"
$detectionMethod = "Registry"
return @{Passed = $true; Details = $details; Method = $detectionMethod}
}
# Method 5: For VMs - check if it's a VM and use alternative detection
$computerSystem = Get-CimInstance -ClassName Win32_ComputerSystem
if ($computerSystem.Model -like "*Virtual*" -or $computerSystem.Manufacturer -like "*VMware*" -or $computerSystem.Manufacturer -like "*Microsoft*" -or $computerSystem.Manufacturer -like "*Parallels*") {
$details += "Virtual Machine detected - using alternative UEFI detection"
# For VMs, check if UEFI firmware is reported
if ($computerSystem -match "UEFI" -or $bios.Description -like "*UEFI*") {
$details += "UEFI detected in VM environment"
$detectionMethod = "VM Detection"
return @{Passed = $true; Details = $details; Method = $detectionMethod}
}
# Additional VM-specific check
$baseboard = Get-CimInstance -ClassName Win32_BaseBoard -ErrorAction SilentlyContinue
if ($baseboard -and ($baseboard.Product -like "*UEFI*" -or $baseboard.Product -like "*EFI*")) {
$details += "UEFI detected via VM baseboard information"
$detectionMethod = "VM Baseboard"
return @{Passed = $true; Details = $details; Method = $detectionMethod}
}
}
$details += "Legacy BIOS detected - UEFI firmware is required for Windows 11"
$detectionMethod = "Multiple Methods"
return @{Passed = $false; Details = $details; Method = $detectionMethod}
} catch {
$details = @("Unable to check UEFI status: $($_.Exception.Message)")
return @{Passed = $false; Details = $details; Method = "Error"}
}
}
# Main script execution
Write-Host "Windows 11 Compatibility Check" -ForegroundColor Green
Write-Host "================================" -ForegroundColor Green
Write-Host "Generating compatibility report..." -ForegroundColor Yellow
# Check if running as administrator
$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")
# Initialize results
$results = @{}
$systemInfo = @{}
$totalChecks = 0
$passedChecks = 0
# Function to add check result
function Add-CheckResult {
param($Name, $Passed, $Details)
$results[$Name] = @{
Name = $Name
Passed = $Passed
Details = $Details
}
$script:totalChecks++
if ($Passed) { $script:passedChecks++ }
}
# Check TPM
try {
$tpm = Get-Tpm -ErrorAction SilentlyContinue
if ($tpm -and $tpm.TpmPresent) {
$details = @(
"TPM is present and enabled",
"Version: $($tpm.ManufacturerVersionFull)",
"Ready: $($tpm.TpmReady)"
)
Add-CheckResult -Name "TPM 2.0" -Passed $true -Details $details
} else {
Add-CheckResult -Name "TPM 2.0" -Passed $false -Details @("TPM 2.0 is required but not detected or enabled")
Write-Host "<WRITE-LOG = ""*TPM 2.0 is required but not detected or enabled*"">"
}
} catch {
Add-CheckResult -Name "TPM 2.0" -Passed $false -Details @("Unable to check TPM: $($_.Exception.Message)")
Write-Host "<WRITE-LOG = ""*TPM 2.0 is required but not detected or enabled*"">"
}
# Check Secure Boot via Registry (no admin needed)
try {
$secureBoot = $false
$details = @()
# Method 1A: Check UEFI Secure Boot status
$uefiSecureBoot = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\State" -Name "UEFISecureBootEnabled" -ErrorAction SilentlyContinue
if ($uefiSecureBoot -and $uefiSecureBoot.UEFISecureBootEnabled -eq 1) {
$secureBoot = $true
$details += "Secure Boot is enabled (Registry method)"
}
# Method 1B: Alternative registry location
elseif (Test-Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot") {
$secureBootValues = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name "*" -ErrorAction SilentlyContinue
if ($secureBootValues -and $secureBootValues.Values -contains 1) {
$secureBoot = $true
$details += "Secure Boot is enabled (Alternative registry)"
} else {
$details += "Secure Boot registry key exists but not enabled"
}
}
# Method 2: WMI/CIM query (may work without admin)
try {
$cimSecureBoot = Get-CimInstance -Namespace "Root\StandardCimv2" -ClassName MSFT_SecureBoot -ErrorAction SilentlyContinue
if ($cimSecureBoot -and $cimSecureBoot.SecureBootEnabled) {
$secureBoot = $true
$details += "Secure Boot is enabled (WMI method)"
}
} catch {
# WMI method failed, continue with other methods
}
if ($secureBoot) {
Add-CheckResult -Name "Secure Boot" -Passed $true -Details $details
} else {
if ($details.Count -eq 0) {
$details += "Secure Boot is disabled or not supported"
}
Add-CheckResult -Name "Secure Boot" -Passed $false -Details $details
Write-Host "<WRITE-LOG = ""*Secure Boot is disabled or not supported*"">"
}
} catch {
Add-CheckResult -Name "Secure Boot" -Passed $false -Details @("Unable to check Secure Boot: $($_.Exception.Message)")
Write-Host "<WRITE-LOG = ""*Secure Boot is disabled or not supported*"">"
}
# Check CPU
try {
$cpu = Get-CimInstance -ClassName Win32_Processor
$cpuName = $cpu.Name.Trim()
$cores = $cpu.NumberOfCores
$threads = $cpu.NumberOfLogicalProcessors
$clockSpeed = [math]::Round($cpu.MaxClockSpeed / 1000, 2)
$architecture = $cpu.AddressWidth
$caption = $cpu.Caption
# Enhanced CPU compatibility check with specific model support
$isCompatible = $false
$compatibilityMessage = ""
$supportedCPUs = @()
# Intel Core Processors (8th Gen and newer)
$supportedCPUs += @(
# Intel 8th/9th Gen
"i3-8[0-9][0-9][0-9]", "i5-8[0-9][0-9][0-9]", "i7-8[0-9][0-9][0-9]", "i9-8[0-9][0-9][0-9]",
"i3-9[0-9][0-9][0-9]", "i5-9[0-9][0-9][0-9]", "i7-9[0-9][0-9][0-9]", "i9-9[0-9][0-9][0-9]",
# Intel 10th/11th Gen
"i3-10[0-9][0-9][0-9]", "i5-10[0-9][0-9][0-9]", "i7-10[0-9][0-9][0-9]", "i9-10[0-9][0-9][0-9]",
"i3-11[0-9][0-9][0-9]", "i5-11[0-9][0-9][0-9]", "i7-11[0-9][0-9][0-9]", "i9-11[0-9][0-9][0-9]",
# Intel 12th/13th/14th Gen
"i3-12[0-9][0-9][0-9]", "i5-12[0-9][0-9][0-9]", "i7-12[0-9][0-9][0-9]", "i9-12[0-9][0-9][0-9]",
"i3-13[0-9][0-9][0-9]", "i5-13[0-9][0-9][0-9]", "i7-13[0-9][0-9][0-9]", "i9-13[0-9][0-9][0-9]",
"i3-14[0-9][0-9][0-9]", "i5-14[0-9][0-9][0-9]", "i7-14[0-9][0-9][0-9]", "i9-14[0-9][0-9][0-9]",
# Intel Xeon
"Xeon.*E-21[0-9][0-9]", "Xeon.*E-22[0-9][0-9]", "Xeon.*E-23[0-9][0-9]", "Xeon.*E-24[0-9][0-9]",
"Xeon W-12[0-9][0-9]", "Xeon W-13[0-9][0-9]", "Xeon W-14[0-9][0-9]", "Xeon W-15[0-9][0-9]",
"Xeon.*Silver", "Xeon.*Gold", "Xeon.*Platinum",
# AMD Ryzen 2000 series and newer
"Ryzen 3 2[0-9][0-9][0-9]", "Ryzen 5 2[0-9][0-9][0-9]", "Ryzen 7 2[0-9][0-9][0-9]", "Ryzen 9 2[0-9][0-9][0-9]",
"Ryzen 3 3[0-9][0-9][0-9]", "Ryzen 5 3[0-9][0-9][0-9]", "Ryzen 7 3[0-9][0-9][0-9]", "Ryzen 9 3[0-9][0-9][0-9]",
"Ryzen 3 4[0-9][0-9][0-9]", "Ryzen 5 4[0-9][0-9][0-9]", "Ryzen 7 4[0-9][0-9][0-9]", "Ryzen 9 4[0-9][0-9][0-9]",
"Ryzen 3 5[0-9][0-9][0-9]", "Ryzen 5 5[0-9][0-9][0-9]", "Ryzen 7 5[0-9][0-9][0-9]", "Ryzen 9 5[0-9][0-9][0-9]",
"Ryzen 3 6[0-9][0-9][0-9]", "Ryzen 5 6[0-9][0-9][0-9]", "Ryzen 7 6[0-9][0-9][0-9]", "Ryzen 9 6[0-9][0-9][0-9]",
"Ryzen 3 7[0-9][0-9][0-9]", "Ryzen 5 7[0-9][0-9][0-9]", "Ryzen 7 7[0-9][0-9][0-9]", "Ryzen 9 7[0-9][0-9][0-9]",
"Ryzen 3 8[0-9][0-9][0-9]", "Ryzen 5 8[0-9][0-9][0-9]", "Ryzen 7 8[0-9][0-9][0-9]", "Ryzen 9 8[0-9][0-9][0-9]",
"Ryzen 3 9[0-9][0-9][0-9]", "Ryzen 5 9[0-9][0-9][0-9]", "Ryzen 7 9[0-9][0-9][0-9]", "Ryzen 9 9[0-9][0-9][0-9]",
# AMD Ryzen Threadripper
"Threadripper 2[0-9][0-9][0-9]", "Threadripper 3[0-9][0-9][0-9]", "Threadripper 3[0-9][0-9][0-9]X",
"Threadripper 4[0-9][0-9][0-9]", "Threadripper 5[0-9][0-9][0-9]", "Threadripper 7[0-9][0-9][0-9]",
# AMD EPYC
"EPYC 7[0-9][0-9][0-9]", "EPYC 7[0-9][0-9][0-9]X", "EPYC 9[0-9][0-9][0-9]", "EPYC 9[0-9][0-9][0-9]X",
# Apple Silicon (for Windows on ARM)
"Apple M[0-9]", "Apple M[0-9] Pro", "Apple M[0-9] Max", "Apple M[0-9] Ultra",
# Qualcomm Snapdragon (Windows on ARM)
"Snapdragon.*8[cx]", "Microsoft SQ[0-9]"
)
# Check if CPU matches supported patterns
$isSupportedModel = $false
foreach ($pattern in $supportedCPUs) {
if ($cpuName -match $pattern) {
$isSupportedModel = $true
break
}
}
# Virtualization support check
$hasVirtualization = $null
try {
$vmMonitor = Get-CimInstance -Namespace "Root\Virtualization\V2" -ClassName Msvm_ComputerSystem -ErrorAction SilentlyContinue
$secFeatures = Get-CimInstance -ClassName Win32_Processor | Select-Object -First 1 | Select-Object -ExpandProperty SecondLevelAddressTranslationExtensions -ErrorAction SilentlyContinue
$hasVirtualization = ($vmMonitor -ne $null) -or ($secFeatures -eq $true)
} catch {
# Virtualization check failed
$hasVirtualization = $null
}
# Determine compatibility
if ($isSupportedModel) {
$isCompatible = $true
$compatibilityMessage = "Supported model"
} elseif ($cores -ge 2 -and $clockSpeed -ge 1.0 -and $architecture -eq 64) {
$isCompatible = $true
$compatibilityMessage = "Meets minimum requirements"
} else {
$isCompatible = $false
$compatibilityMessage = "Does not meet requirements"
}
# Build details array
$details = @(
"Processor: $cpuName",
"Cores: $cores",
"Threads: $threads",
"Clock Speed: $clockSpeed GHz",
"Architecture: $architecture-bit",
"Compatibility: $compatibilityMessage"
)
# Add virtualization info if available
if ($hasVirtualization -eq $true) {
$details += "Virtualization: Supported"
} elseif ($hasVirtualization -eq $false) {
$details += "Virtualization: Not available"
}
# Add model support info
if ($isSupportedModel) {
$details += "Model Support: Officially supported"
} else {
$details += "Model Support: Check manufacturer compatibility"
}
Add-CheckResult -Name "Processor" -Passed $isCompatible -Details $details
} catch {
Add-CheckResult -Name "Processor" -Passed $false -Details @("Unable to check processor: $($_.Exception.Message)")
Write-Host "<WRITE-LOG = ""*Unable to check processor: $($_.Exception.Message)*"">"
}
# Check RAM
try {
$ram = Get-CimInstance -ClassName Win32_ComputerSystem
$totalRAM = [math]::Round($ram.TotalPhysicalMemory / 1GB, 2)
$details = @("Installed RAM: $totalRAM GB")
$ramCompatible = $totalRAM -ge 4
Add-CheckResult -Name "Memory (RAM)" -Passed $ramCompatible -Details $details
} catch {
Add-CheckResult -Name "Memory (RAM)" -Passed $false -Details @("Unable to check RAM: $($_.Exception.Message)")
Write-Host "<WRITE-LOG = ""*Unable to check RAM: $($_.Exception.Message)*"">"
}
# Check Storage
try {
$storage = Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DeviceID='C:'"
$freeSpace = [math]::Round($storage.FreeSpace / 1GB, 2)
$totalSpace = [math]::Round($storage.Size / 1GB, 2)
$details = @(
"Total space: $totalSpace GB",
"Free space: $freeSpace GB"
)
$storageCompatible = $freeSpace -ge 64
Add-CheckResult -Name "Storage" -Passed $storageCompatible -Details $details
} catch {
Add-CheckResult -Name "Storage" -Passed $false -Details @("Unable to check storage: $($_.Exception.Message)")
Write-Host "<WRITE-LOG = ""*Unable to check storage: $($_.Exception.Message)*"">"
}
# Check UEFI
$uefiResult = Test-UEFI
Add-CheckResult -Name "UEFI Firmware" -Passed $uefiResult.Passed -Details $uefiResult.Details
# Check Graphics
try {
$graphics = Get-CimInstance -ClassName Win32_VideoController | Where-Object {$_.Name -notlike "*Remote*"}
$wddmCompatible = $false
foreach ($controller in $graphics) {
if ($controller.DriverVersion -and $controller.Name -notlike "*Remote*") {
$wddmCompatible = $true
break
}
}
if ($wddmCompatible) {
Add-CheckResult -Name "Graphics" -Passed $true -Details @("Compatible graphics adapter detected")
} else {
Add-CheckResult -Name "Graphics" -Passed $false -Details @("WDDM 2.0 compatible driver may be required")
Write-Host "<WRITE-LOG = ""*WDDM 2.0 compatible driver may be required*"">"
}
} catch {
Add-CheckResult -Name "Graphics" -Passed $false -Details @("Unable to check graphics: $($_.Exception.Message)")
}
# Check Display
try {
$display = Get-CimInstance -ClassName Win32_VideoController | Where-Object {$_.Name -notlike "*Remote*"}
$horizontalResolution = 0
foreach ($controller in $display) {
if ($controller.CurrentHorizontalResolution -gt $horizontalResolution) {
$horizontalResolution = $controller.CurrentHorizontalResolution
}
}
$displayCompatible = $horizontalResolution -ge 720
if ($displayCompatible) {
Add-CheckResult -Name "Display" -Passed $true -Details @("Display resolution: ${horizontalResolution}p (meets requirements)")
} else {
Add-CheckResult -Name "Display" -Passed $false -Details @("Display resolution may not meet minimum requirements")
Write-Host "<WRITE-LOG = ""*Display resolution may not meet minimum requirements*"">"
}
} catch {
Add-CheckResult -Name "Display" -Passed $false -Details @("Unable to check display: $($_.Exception.Message)")
}
# Gather system information
try {
$os = Get-CimInstance -ClassName Win32_OperatingSystem
$computer = Get-CimInstance -ClassName Win32_ComputerSystem
$bios = Get-CimInstance -ClassName Win32_BIOS
$systemInfo["Operating System"] = $os.Caption
$systemInfo["OS Version"] = $os.Version
$systemInfo["Manufacturer"] = $computer.Manufacturer
$systemInfo["Model"] = $computer.Model
$systemInfo["BIOS Version"] = $bios.SMBIOSBIOSVersion
$systemInfo["Last Boot"] = $os.LastBootUpTime.ToString("yyyy-MM-dd HH:mm:ss")
$systemInfo["Administrator"] = if ($isAdmin) { "Yes" } else { "No" }
} catch {
Write-Warning "Unable to gather complete system information"
}
# Generate HTML report
$htmlContent = New-HTMLReport -Results $results -SystemInfo $systemInfo -Passed $passedChecks -Total $totalChecks
# Save to desktop
try {
$isComp = "Not_Compatible"
if($passedChecks -eq $totalChecks){
$isComp = "Compatible"
Write-Host "<WRITE-LOG = ""*Device is compatible with Windows 11*"">"
}else{
Write-Host "<WRITE-LOG = ""*Device is NOT compatible with Windows 11*"">"
}
$OutputPath = "$env:USERPROFILE\Desktop\"+$isComp+"-"+($computer).Name+".html"
<# You can also save to fileshare instead just set $OutputPath as needed see ex.
$OutputPath = "\\servername\share\"+$isComp+"-"+($computer).Name+".html"
#>
$htmlContent | Out-File -FilePath $OutputPath -Encoding UTF8
Write-Host "<WRITE-LOG = ""*Report saved to: $OutputPath*"">" -ForegroundColor Cyan
} catch {
Write-Host "❌ Error saving report: $($_.Exception.Message)" -ForegroundColor Red
}
Write-Host "`nCompatibility Summary: $passedChecks/$totalChecks requirements passed" -ForegroundColor $(if ($passedChecks -eq $totalChecks) { "Green" } else { "Yellow" })Run it across your fleet
This script runs as-is on a single host. Paste it into ServerEngine to schedule it, run it on a whole server group in parallel, and keep the credentials out of the file — see the scripts documentation and the credential store.
More in Checks & Diagnostics
Ready when you are.
Try ServerEngine free for 7 days.