Back to Resources
Level
Script
Patching
Upgrading large fleets of Windows 10 devices to Windows 11 can be time-consuming and error-prone when done manually, especially for IT Professionals managing numerous endpoints. This script automates the entire process using Microsoft’s official Installation Assistant, helping ensure your transitions remain consistent, efficient, and less prone to human oversight.
This script first checks for or creates a temporary folder, then downloads the Windows 11 Installation Assistant directly from Microsoft, storing it locally. It proceeds to launch a silent upgrade with minimal user interaction, tracks any error codes, and logs issues to assist troubleshooting. Once the process is complete, the script cleans up the installer to reclaim space and neatly finalizes the upgrade.
With built-in logging, it offers detailed insights into both successful upgrades and potential failures, allowing you to quickly pinpoint and address problems. The entire flow runs under system permissions, letting you execute remote or automated upgrades without manual steps.
1<#
2This resource is provided as a convenience for Level users. We cannot
3guarantee it will work in all environments. Please test before deploying
4to your production environment. We welcome contributions to our community
5library
6
7Level Library
8https://level.io/library/script-upgrade-to-windows-11
9#>
10
11# Step 1: Setup
12Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [INFO] - Script started..."
13
14# Define necessary paths and variables
15$installerPath = "C:\temp\Windows11UpdateAssistant.exe"
16$tempDir = "C:\temp"
17
18# Step 2: Check if temporary directory exists, create if not
19if (-Not (Test-Path $tempDir)) {
20 New-Item -ItemType Directory -Path $tempDir -Force | Out-Null
21 Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [INFO] - Created directory '$tempDir'."
22} else {
23 Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [INFO] - Directory '$tempDir' already exists."
24}
25
26# Step 3: Download the Windows 11 Installation Assistant
27$url = "https://go.microsoft.com/fwlink/?linkid=2171764"
28try {
29 Invoke-WebRequest -Uri $url -OutFile $installerPath -ErrorAction Stop
30 $FileSize = [math]::round((Get-Item -Path $installerPath).Length/1MB,2)
31 Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [INFO] - Windows 11 Installation Assistant downloaded to '$installerPath' - $FileSize MB."
32} catch {
33 Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [ERROR] - Failed to download Windows 11 Installation Assistant. $_"
34 exit 1
35}
36
37# Step 4: Start the Windows 11 upgrade process
38Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [INFO] - Starting Windows 11 upgrade process."
39$process = Start-Process -FilePath $installerPath -ArgumentList "/quietinstall /skipeula /auto upgrade /NoRestartUI /noreboot /copylogs $tempDir" -PassThru -Wait
40
41# Step 5: Check if the process was successfully initiated and check the exit code
42if ($process.ExitCode -ne 0) {
43 Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [ERROR] - The Windows 11 upgrade process failed with exit code $($process.ExitCode)."
44
45 # Step 6: Extract errors from setup logs if available
46 if (Test-Path $tempDir) {
47 $setupActLog = Join-Path -Path $tempDir -ChildPath "setupact.log"
48 $setupErrLog = Join-Path -Path $tempDir -ChildPath "setuperr.log"
49
50 # Extract errors and warnings from setupact.log
51 if (Test-Path $setupActLog) {
52 Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [DEBUG] - Extracting warnings and errors from '$setupActLog'."
53 Select-String -Path $setupActLog -Pattern "Error", "Warning" | ForEach-Object {
54 Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [DEBUG] - $($_.Line)"
55 }
56 }
57
58 # Extract errors and warnings from setuperr.log
59 if (Test-Path $setupErrLog) {
60 Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [DEBUG] - Extracting warnings and errors from '$setupErrLog'."
61 Select-String -Path $setupErrLog -Pattern "Error", "Warning" | ForEach-Object {
62 Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [DEBUG] - $($_.Line)"
63 }
64 }
65 }
66
67 exit 1
68} else {
69 Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [INFO] - The Windows 11 upgrade process completed successfully with exit code 0."
70}
71
72# Step 7: Clean up the installer
73if (Test-Path $installerPath) {
74 Remove-Item -Path $installerPath -Force
75 Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [INFO] - Cleaned up installer from '$installerPath'."
76}
77
78# Step 8: Exit with a success code
79exit 0
C:\\temp
directory, which you can inspect for more information.C:\\temp
, specifically in setupact.log
and setuperr.log
, which should contain clues about errors or warnings encountered during the upgrade process.Upgrade to Windows 11
This PowerShell script automates the Windows 11 upgrade process by downloading the Windows 11 Installation Assistant, initiating the upgrade with specific arguments, and monitoring the process. It includes error handling, log extraction for debugging, and cleanup of temporary files to ensure a streamlined upgrade experience.
PowerShell
28800
Local system
Explore more automations, scripts, and policies to further enhance your IT operations.