Windows 11 Upgrade Script | RMM Deployment

Table of Contents
Intro
Windows 10 will reach end of support on October 14, 2025, here is a script to help make the upgrade process to Windows 11 easier. I first tried to make a script that would utilize the PC Health Check app from Microsoft, the official way to confirm if a computer can receive Windows 11 but found the app was not able to be used since commands pushed to it don’t seem to work. Instead, I created a script with the help of ChatGPT that will check various attributes in Windows and if they pass will run the upgrade.
PowerShell Script Checks
More Context
The script will first check if the OS is Windows 10 and not a server OS, exit if Windows 11. Then it will check the following:
- Check for TPM 2.0.
- Check for UEFI.
- Check for Secure Boot.
- Check for free space.
- Check for compatible Intel or AMD processor.
The script will output which checks fail for a machine. I configured an Extra Data Value in ConnectWise for this so I can quickly see if a machine can be upgraded or not and why it failed.
The script downloads the Windows 11 Installation Assistant to the ConnectWise working directory at: C:\Windows\LTSvc which is automatically created during install of the ConnectWise Automate agent so change that path accordingly for your specific needs.
Here are multiple examples of what the EDV reports after the script ran on various devices.
Here also are the requirements for Windows 11.

Windows 11 Checks + Upgrade | PowerShell Script
More Context
Make sure you query the list of processors used in your organization and then include them in the script below if missing.
# Check if the OS is Windows 10 and not a Server OS
$OSInfo = Get-ComputerInfo
if ($OSInfo.OsArchitecture -eq "64-bit" -and $OSInfo.OsName -match "Windows 10" -and $OSInfo.OsName -notmatch "Server") {
Write-Host "Windows 10 detected, continuing compatibility check..." -ForegroundColor Cyan
} else {
Write-Host "This script is intended for Windows 10 only. It will not run on Windows Server or other versions." -ForegroundColor Red
exit
}
# Check if the OS is Windows 11
if ($OSInfo.OsArchitecture -eq "64-bit" -and $OSInfo.OsName -match "Windows 11") {
Write-Host "Windows 11 is already installed." -ForegroundColor Green
exit
}
Function Check-TPM {
try {
$TPMDevice = Get-CimInstance -Namespace "Root\CIMv2\Security\MicrosoftTpm" -ClassName Win32_Tpm | Where-Object { $_.SpecVersion -match "2.0" }
if ($TPMDevice) {
return $true
} else {
Write-Host "TPM 2.0 is not present or enabled." -ForegroundColor Red
return $false
}
} catch {
Write-Host "Error retrieving TPM information. Ensure the TPM module is accessible." -ForegroundColor Red
return $false
}
}
Function Check-UEFI {
try {
$FirmwareType = (Get-ComputerInfo -Property BiosFirmwareType | Format-Table -HideTableHeaders | Out-String).Trim().ToUpper()
if ($FirmwareType -ne "UEFI") {
Write-Host "System is not using UEFI." -ForegroundColor Red
return $false
}
return $true
} catch {
Write-Host "Error checking firmware type. Ensure system supports UEFI." -ForegroundColor Red
return $false
}
}
Function Check-SecureBoot {
try {
$SecureBootState = Confirm-SecureBootUEFI
if (-not $SecureBootState) {
Write-Host "Secure Boot is not enabled." -ForegroundColor Red
return $false
}
return $true
} catch {
Write-Host "Error checking Secure Boot state. Ensure Secure Boot is supported." -ForegroundColor Red
return $false
}
}
Function Check-FreeSpace {
try {
$CDrive = Get-PSDrive -Name C
$RequiredSpaceGB = 64 # Minimum free space required in GB
$FreeSpaceGB = [math]::Round($CDrive.Free / 1GB, 2)
if ($FreeSpaceGB -lt $RequiredSpaceGB) {
Write-Host "Not enough free space on C: drive ($FreeSpaceGB GB). Required: $RequiredSpaceGB GB." -ForegroundColor Red
return $false
}
return $true
} catch {
Write-Host "Error checking disk space. Ensure the C: drive is accessible." -ForegroundColor Red
return $false
}
}
Function Check-Processor {
try {
$ProcessorName = (Get-CimInstance -ClassName Win32_Processor).Name.Trim()
# Updated lists of supported processors for Intel and AMD
$SupportedIntelProcessors = @(
"Intel.*Core.*i3-8",
"Intel.*Core.*i5-8",
"Intel.*Core.*i7-8",
"Intel.*Core.*i9-8",
"Intel.*Core.*i3-9",
"Intel.*Core.*i5-9",
"Intel.*Core.*i7-9",
"Intel.*Core.*i9-9",
"Intel.*Core.*i3-10",
"Intel.*Core.*i5-10",
"Intel.*Core.*i7-10",
"Intel.*Core.*i9-10",
"Intel.*Core.*i3-11",
"Intel.*Core.*i5-11",
"Intel.*Core.*i7-11",
"Intel.*Core.*i9-11",
"Intel.*Core.*i3-12",
"Intel.*Core.*i5-12",
"Intel.*Core.*i7-12",
"Intel.*Core.*i9-12",
"Intel.*Core.*i3-13",
"Intel.*Core.*i5-13",
"Intel.*Core.*i7-13",
"Intel.*Core.*i9-13",
"Intel.*Xeon.*E-2",
"Intel.*Xeon.*W-1",
"Intel.*Pentium.*G",
"Intel.*Celeron.*G"
)
$SupportedAMDProcessors = @(
"AMD.*Ryzen.*3.*2300",
"AMD.*Ryzen.*5.*2500",
"AMD.*Ryzen.*7.*2700",
"AMD.*Ryzen.*9.*2900",
"AMD.*Ryzen.*3.*3200",
"AMD.*Ryzen.*5.*3400",
"AMD.*Ryzen.*7.*3700",
"AMD.*Ryzen.*9.*3900",
"AMD.*Ryzen.*3.*4300",
"AMD.*Ryzen.*5.*4500",
"AMD.*Ryzen.*7.*4700",
"AMD.*Ryzen.*9.*4900",
"AMD.*Ryzen.*3.*5300",
"AMD.*Ryzen.*5.*5500",
"AMD.*Ryzen.*7.*5700",
"AMD.*Ryzen.*9.*5900",
"AMD.*EPYC",
"AMD.*Athlon.*Gold",
"AMD.*Athlon.*Silver"
)
# Combine both Intel and AMD processor lists into a single pattern
$SupportedProcessors = ($SupportedIntelProcessors + $SupportedAMDProcessors) -join "|"
# Match the processor name against the combined pattern
if ($ProcessorName -match $SupportedProcessors) {
return $true
} else {
Write-Host "Unsupported processor detected: $ProcessorName" -ForegroundColor Red
return $false
}
} catch {
Write-Host "Error checking processor information. Ensure the system allows querying the processor details." -ForegroundColor Red
return $false
}
}
Write-Host "Starting Windows 11 Compatibility Check..." -ForegroundColor Cyan
# Run all checks
$TPMCheck = Check-TPM
$UEFICheck = Check-UEFI
$SecureBootCheck = Check-SecureBoot
$FreeSpaceCheck = Check-FreeSpace
$ProcessorCheck = Check-Processor
# Final compatibility evaluation
if ($TPMCheck -and $SecureBootCheck -and $UEFICheck -and $FreeSpaceCheck -and $ProcessorCheck) {
Write-Host "System is compatible with Windows 11." -ForegroundColor Green
########### Begin Script for Windows 11 Upgrade
$dir = 'C:\Windows\LTSvc\Win11Upgrade'
$url = 'https://go.microsoft.com/fwlink/?linkid=2171764'
$file = "$dir\Windows11InstallationAssistant.exe"
mkdir $dir -force
cd $dir
Start-BitsTransfer -Source $url -Destination $file
.\Windows11InstallationAssistant.exe /QuietInstall /SkipEULA /NoRestartUI
########### End Script
} else {
Write-Host "System does not meet all requirements for Windows 11." -ForegroundColor Red
}
Conclusion
Hopefully this helps, I tested on a couple machines and it worked great!

My name is Dex Sandel, author at WinReflection.
I am a Christian, conservative, and truth seeker that is not afraid to be vocal on important or controversial issues, silence leads to death. When a person has that courage the enemy tries to send haters and wolves in sheep’s clothing their way. There are many rewards earned in Heaven for those that refuse to give up. There’s more to life than the worldly status quo and that’s why many are sad and depressed, they’re suffocating! Truth and purpose can bring fresh air into one’s life and that’s my mission.
The best is yet to come, and nothing can stop what’s coming!
John 3:16: For God so loved the world that he gave his one and only Son, that whoever believes in him shall not perish but have eternal life.
Leave a Reply
Want to join the discussion?Feel free to contribute!