Back

Perform the upgrade from Windows 10 to Windows 11

Learn how to check Windows 10 device eligibility for an upgrade to Windows 11 and automate the upgrade process using FleetDM policies and PowerShell scripts, including device classification, eligibility assessment, and triggering the upgrade installation.

This article details the process to check which Windows 10 devices are eligible for an upgrade to Windows 11, and automatically initiate that upgrade using FleetDM policies and PowerShell scripts.

The procedure includes:

  • Detecting and storing required system components (TPM 2.0 and Secure Boot) in the registry
  • Validating hardware and software requirements to determine upgrade eligibility
  • Running an automated download and silent installation of Windows 11 on compliant devices

 

Classify devices with TPM and Secure Boot present

Create the detection policy (FleetDM registry)

Use the following query to verify the presence of registry keys that will store TPM and Secure Boot status:

SELECT 1 WHERE EXISTS (      SELECT 1 FROM registry      WHERE path = 'HKEY_LOCAL_MACHINE\Software\FleetDM\TPMVersion'    )    AND EXISTS (      SELECT 1 FROM registry      WHERE path = 'HKEY_LOCAL_MACHINE\Software\FleetDM\SecureBoot'    );

Run the associated script (populate the registry)

Attach this PowerShell script to the policy above. It detects TPM version and Secure Boot status, then writes them to the Windows registry for FleetDM.

$TPM = Get-WmiObject -Namespace "Root\CIMv2\Security\MicrosoftTpm" -Class Win32_Tpm$SecureBoot = Confirm-SecureBootUEFI$TPMVersion = $TPM.SpecVersion$SecureBootEnabled = if ($SecureBoot) { 1 } else { 0 }# Write values to the registry (example)New-Item -Path "HKLM:\Software\FleetDM" -Force | Out-NullSet-ItemProperty -Path "HKLM:\Software\FleetDM" -Name "TPMVersion" -Value $TPMVersionSet-ItemProperty -Path "HKLM:\Software\FleetDM" -Name "SecureBoot" -Value $SecureBootEnabled

Expected result: HKLM\Software\FleetDM\TPMVersion and HKLM\Software\FleetDM\SecureBoot are created/updated.


 

Assess a Windows 10 device’s eligibility for Windows 11

Create the following policy to validate minimum requirements (RAM, CPU cores, architecture, TPM 2.0, Secure Boot) and exclude non-compliant devices.

SELECT 1 FROM os_version as os JOIN system_info as si WHERE    os.name NOT LIKE 'Microsoft Windows 10%'    OR si.physical_memory < 4 * 1024 * 1024 * 1024    OR si.cpu_physical_cores < 2    OR si.cpu_type NOT LIKE '%x86_64%'    OR NOT EXISTS (      SELECT * FROM registry      WHERE path = 'HKEY_LOCAL_MACHINE\Software\FleetDM\TPMVersion'        AND data LIKE '2%'    )    OR NOT EXISTS (      SELECT * FROM registry      WHERE path = 'HKEY_LOCAL_MACHINE\Software\FleetDM\SecureBoot'        AND data = '1'    );

Interpretation: the query returns 1 if the device is not a compliant Windows 10. Use it as a non-compliance policy to keep only eligible devices (those for which the query does not return 1).


 

Trigger the Windows 11 upgrade (eligible devices)

Attach the deployment script below to compliant devices. It downloads the Windows 11 ISO, mounts the image, copies sources locally, and schedules a silent setup under SYSTEM.

# ImportsImport-Module BitsTransfer# Variables$uri = "https://production-bucket-public-files.s3.eu-west-3.amazonaws.com/Win11_24H2_French_x64.iso"$destination = "C:\Win11.iso"$log = "C:\logs\download_win11_iso.log"# Create the logs folder if it doesn't existif (-not (Test-Path -Path "C:\logs")) {    New-Item -Path "C:\logs" -ItemType Directory | Out-Null}# Start the downloadtry {    "`n[$(Get-Date)] Starting download..." | Out-File -Append $log    if (-not (Test-Path $destination)){      Start-BitsTransfer -Source $uri -Destination $destination    }    "`n[$(Get-Date)] Download completed successfully." | Out-File -Append $log} catch {    "`n[$(Get-Date)] Error during download: $_" | Out-File -Append $log}# Additional variables$isoPath = "C:\Win11.iso"$setupFolder = "C:\Temp\Win11Files"$taskName = "Win11SilentUpgrade"# Step 1 - Mount the ISOMount-DiskImage -ImagePath $isoPath -PassThru | Out-NullStart-Sleep -Seconds 2$vol = Get-Volume -DiskImage (Get-DiskImage -ImagePath $isoPath)$driveLetter = $vol.DriveLetter# Step 2 - Copy ISO content locallyNew-Item -ItemType Directory -Force -Path $setupFolder | Out-NullCopy-Item "$driveLetter`:\*" -Destination $setupFolder -Recurse# Unmount the ISODismount-DiskImage -ImagePath $isoPath# Step 3 - Create and schedule the installation task$action = New-ScheduledTaskAction -Execute "C:\Temp\Win11Files\setup.exe" -Argument "/auto upgrade /migratedrivers none /resizerecoverypartition enable /dynamicupdate disable /eula accept /quiet /noreboot /uninstall disable /compat ignorewarning /copylogs C:\logs\WinSetup.log"$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest$task = New-ScheduledTask -Action $action -Principal $principal -Trigger (New-ScheduledTaskTrigger -Once -At (Get-Date).AddMinutes(1))Register-ScheduledTask -TaskName $taskName -InputObject $task -Force# Step 4 - Start the task immediatelyStart-ScheduledTask -TaskName $taskName

Was this article helpful?

Give feedback about this article

Can’t find what you’re looking for?

Our customer care team is here for you.

Contact us

Knowledge Base Software powered by Helpjuice