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 make the upgrade process easier. I first tried to make a process that would utilize the PC Health Check app from Microsoft, the official way to confirm but found the app was not able to scripted and forced to run via command line. 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.
Checks
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 Windows11 Installation Assistant to the ConnectWise working directory at: C:\Windows\LTSvc which is automatically created during install of the agent so change that path accordingly for your needs.
Here are multiple examples of what the EDV reports after the script ran on various devices.
Here are the requirements for Windows 11.
Script
# 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, a blog which aims to help others on various IT and Christian related subjects. DON’T TREAD ON ME! The best is yet to come, and nothing can stop what’s coming!
You all have a greater destiny in Christ, should you choose to ‘follow’ Him, not just believe. Many of you feel lost, without drive, and lack a greater purpose in your life causing depression, sadness, anxiety, and loneliness. Working your 9-5 job isn’t your primary purpose. So, then what is? That’s for you to discover, but hopefully I can provide some new unlocks along your path.
What will ‘you’ do, and what will your destiny be?
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!