This article explains how to upgrade Windows 10 devices to Windows 11 using the official Microsoft ISO image. This method is useful when you want to perform a controlled upgrade outside of Windows Update, or when internet restrictions require manual ISO downloads.
⚠️ Important: Always replace the ISO download links in the script with the latest Windows 11 ISO from Microsoft’s official site: Download Windows 11 Disk Image (ISO).
Prerequisites
System Requirements
TPM 2.0 must be enabled.
Secure Boot must be enabled.
Minimum 25 GB free disk space on the
C:
drive.Device should meet all Windows 11 requirements.
Admin Access
Run the script with administrative privileges.PowerShell Version
PowerShell 5.1 or later is required.
Upgrade Process
- Download and Save the Script
Save the script below into a file namedUpgrade-Win10ToWin11.ps1
. Edit ISO URLs
Update the$isoDownloadUrl_en_us
and$isoDownloadUrl_en_international
values with the latest ISO links from Microsoft.Example:
$isoDownloadUrl_en_us = "<LATEST MICROSOFT ISO LINK for English US>"
$isoDownloadUrl_en_international = "<LATEST MICROSOFT ISO LINK for English International>"
Run the Script through remote scripting
Go to EM>Actions>Remote Scripting
Run the below attached script.Script Flow
The script will:Detect system language and select the correct ISO.
Verify architecture, TPM 2.0, and Secure Boot.
Check disk space availability.
Download the ISO if not already present.
Mount the ISO.
Run
setup.exe
silently with upgrade arguments.Unmount the ISO after initiating the upgrade.
Full Script
# Log file in temp directory
$logFile = "C:\windows11-upgrade.log"
# ISO URLs (replace with the latest from Microsoft)
$isoDownloadUrl_en_us = "<LATEST MICROSOFT ISO LINK for English US>"
$isoDownloadUrl_en_international = "<LATEST MICROSOFT ISO LINK for English International>"
# ISO paths
$isoPath_en_us = "C:\windows11\Win11_24H2_English_x64.iso"
$isoPath_en_international = "C:\windows11\Win11_24H2_EnglishInternational_x64.iso"
# Mount path variable
$isoMountPath = ""
# Function to log messages
function Write-Log {
param ([string]$message)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
"$timestamp : $message" | Tee-Object -FilePath $logFile -Append
}
# Start logging
Write-Log "Starting Windows 11 upgrade process..."
# Detect system UI language
$systemLanguage = (Get-WinSystemLocale).Name
Write-Log "Detected system language: $systemLanguage"
# Select correct ISO URL and path based on language
if ($systemLanguage -eq "en-US") {
$isoDownloadUrl = $isoDownloadUrl_en_us
$isoPath = $isoPath_en_us
Write-Log "Using en-US ISO and download URL."
} else {
$isoDownloadUrl = $isoDownloadUrl_en_international
$isoPath = $isoPath_en_international
Write-Log "Using International English ISO and download URL."
}
# Check system architecture
$arch = (Get-CimInstance Win32_OperatingSystem).OSArchitecture
Write-Log "System architecture: $arch"
# Check TPM 2.0
$tpm = Get-WmiObject -Namespace "Root\CIMV2\Security\MicrosoftTpm" -Class Win32_Tpm -ErrorAction SilentlyContinue
if ($tpm -and $tpm.SpecVersion -like "*2.0*") {
Write-Log "TPM 2.0 is present."
} else {
Write-Log "TPM 2.0 is missing or inaccessible."
exit 1
}
# Check Secure Boot
try {
$sb = Confirm-SecureBootUEFI
Write-Log "Secure Boot: $sb"
} catch {
Write-Log "Secure Boot: Not supported or access denied."
exit 1
}
# Check free disk space
$freeSpaceGB = [math]::Round((Get-PSDrive C).Free / 1GB, 2)
Write-Log "Free space on C: $freeSpaceGB GB"
if ($freeSpaceGB -lt 25) {
Write-Log "ERROR: Not enough free disk space. Exiting..."
exit 1
}
# Create target folder if not exists
if (-not (Test-Path "C:\windows11")) {
New-Item -ItemType Directory -Path "C:\windows11" | Out-Null
Write-Log "Created C:\windows11 directory."
}
# Download ISO if not already present
if (-not (Test-Path $isoPath)) {
Write-Log "Downloading ISO file from Microsoft..."
try {
$ProgressPreference = 'SilentlyContinue'
Invoke-WebRequest -Uri $isoDownloadUrl -OutFile $isoPath -UseBasicParsing -ErrorAction Stop | Out-Null
Write-Log "ISO successfully downloaded to: $isoPath"
} catch {
Write-Log "ERROR: Failed to download ISO. $_"
exit 1
}
} else {
Write-Log "ISO already exists at: $isoPath"
}
# Mount ISO
Write-Log "Mounting ISO..."
try {
$mount = Mount-DiskImage -ImagePath $isoPath -PassThru -ErrorAction Stop
$attempt = 0
$maxAttempts = 10
$isoMountPath = $null
while ($attempt -lt $maxAttempts -and -not $isoMountPath) {
Start-Sleep -Seconds 1
$volumes = Get-Volume -DiskImage $mount -ErrorAction SilentlyContinue
foreach ($vol in $volumes) {
if ($vol.DriveLetter) {
$isoMountPath = "$($vol.DriveLetter):"
break
}
}
$attempt++
}
if ($isoMountPath) {
Write-Log "ISO mounted at: $isoMountPath"
} else {
Write-Log "ERROR: ISO mounted but no drive letter assigned after $maxAttempts seconds."
exit 1
}
} catch {
Write-Log "ERROR: Failed to mount ISO. $_"
exit 1
}
# Start upgrade silently
$setupExe = Join-Path $isoMountPath "setup.exe"
Write-Log "Starting Windows 11 silent upgrade using: $setupExe"
try {
Start-Process -FilePath $setupExe -ArgumentList "/auto upgrade /quiet /noreboot /eula accept /compat ignorewarning /dynamicupdate disable /showoobe none" -Wait -NoNewWindow
Write-Log "Upgrade process initiated successfully."
} catch {
Write-Log "ERROR: Failed to start Windows 11 setup. $_"
exit 1
}
# Unmount ISO
Write-Log "Unmounting ISO..."
try {
Dismount-DiskImage -ImagePath $isoPath
Write-Log "ISO unmounted successfully."
} catch {
Write-Log "ERROR: Failed to unmount ISO. $_"
}
# Final log
Write-Log "Upgrade script complete. Please reboot to finish the upgrade."
Logs
All logs are stored at:
C:\windows11-upgrade.log
Final Step
After the script completes, restart the system to finalize the Windows 11 upgrade.
Was this article helpful?
That’s Great!
Thank you for your feedback
Sorry! We couldn't be helpful
Thank you for your feedback
Feedback sent
We appreciate your effort and will try to fix the article