Back to Resources

Level Verified

Upgrade to Windows 11 Script

Created by

Level

Type

Script

Category

Patching

Platforms
WindowsApple iOSLinux

Problem Overview

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.

Description

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.

Script

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

Use Cases

  • Performing bulk in-place upgrades from Windows 10 to Windows 11 across multiple clients
  • Simplifying OS deployment for newly procured devices or refresh cycles
  • Automating standardization to Windows 11 for compliance or security requirements
  • Reducing manual oversight during major version migrations

Recommendations

  • Always test in a non-production environment before large-scale deployments
  • Configure a script-based monitor in Level to run this script on-demand for one-off upgrades
  • Consider building a tag based automation in Level that executes this script on targeted endpoints. See our Windows 11 Upgrade Automation
  • Verify hardware readiness (such as disk space, TPM version, and CPU requirements) to avoid unexpected failures
  • Ensure endpoints have sufficient internet connectivity for the Installation Assistant download
  • Keep logs for troubleshooting and consult the official Microsoft documentation for known upgrade issues

FAQ

  • Does the script automatically reboot the device?
    By default, the script performs a silent install without forcing a reboot, allowing admins to schedule or manually reboot at a convenient time.
  • What happens if the device does not meet Windows 11 hardware requirements?
    The Installation Assistant may fail partway, generating an error code and logging details in the C:\\temp directory, which you can inspect for more information.
  • Do I need to run this script with elevated permissions?
    Yes, Level will execute the script with system-level permissions, which is required to perform OS upgrades.
  • Can I customize the install arguments?
    The script references Microsoft’s upgrade tool with set parameters, but you can modify the argument list for advanced use cases—just thoroughly test any changes before rollout.
  • Where can I find logs if something goes wrong?
    The script logs to C:\\temp, specifically in setupact.log and setuperr.log, which should contain clues about errors or warnings encountered during the upgrade process.

Included with this Script:

Below is a list of what you can expect to find when importing this Script.

Script details:

The following data and settings will be imported with your script.

Script Name

Upgrade to Windows 11

Description

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.

Language

PowerShell

Timeout (In Seconds)

28800

Run As

Local system

Import into Level

Related resources

Explore more automations, scripts, and policies to further enhance your IT operations.

View all resources