Level Verified

Upgrade to Windows 11 Script

Effortlessly transition Windows 10 systems to Windows 11. This script downloads and launches the official Microsoft Installation Assistant, automates the upgrade process, and cleans up afterward—perfect for seamless OS migrations at scale.

Import into Level

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.

PowerShell 28800s timeout Runs as Local system Windows
<#
This resource is provided as a convenience for Level users. We cannot 
guarantee it will work in all environments. Please test before deploying 
to your production environment. We welcome contributions to our community 
library

Level Library
https://level.io/library/script-upgrade-to-windows-11
#>

# Step 1: Setup
Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [INFO] - Script started..."

# Define necessary paths and variables
$installerPath = "C:\temp\Windows11UpdateAssistant.exe"
$tempDir = "C:\temp"

# Step 2: Check if temporary directory exists, create if not
if (-Not (Test-Path $tempDir)) {
    New-Item -ItemType Directory -Path $tempDir -Force | Out-Null
    Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [INFO] - Created directory '$tempDir'."
} else {
    Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [INFO] - Directory '$tempDir' already exists."
}

# Step 3: Download the Windows 11 Installation Assistant
$url = "https://go.microsoft.com/fwlink/?linkid=2171764"
try {
    Invoke-WebRequest -Uri $url -OutFile $installerPath -ErrorAction Stop
    $FileSize = [math]::round((Get-Item -Path $installerPath).Length/1MB,2)
    Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [INFO] - Windows 11 Installation Assistant downloaded to '$installerPath' - $FileSize MB."
} catch {
    Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [ERROR] - Failed to download Windows 11 Installation Assistant. $_"
    exit 1
}

# Step 4: Start the Windows 11 upgrade process
Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [INFO] - Starting Windows 11 upgrade process."
$process = Start-Process -FilePath $installerPath -ArgumentList "/quietinstall /skipeula /auto upgrade /NoRestartUI /noreboot /copylogs $tempDir" -PassThru -Wait

# Step 5: Check if the process was successfully initiated and check the exit code
if ($process.ExitCode -ne 0) {
    Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [ERROR] - The Windows 11 upgrade process failed with exit code $($process.ExitCode)."
    
    # Step 6: Extract errors from setup logs if available
    if (Test-Path $tempDir) {
        $setupActLog = Join-Path -Path $tempDir -ChildPath "setupact.log"
        $setupErrLog = Join-Path -Path $tempDir -ChildPath "setuperr.log"

        # Extract errors and warnings from setupact.log
        if (Test-Path $setupActLog) {
            Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [DEBUG] - Extracting warnings and errors from '$setupActLog'."
            Select-String -Path $setupActLog -Pattern "Error", "Warning" | ForEach-Object {
                Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [DEBUG] - $($_.Line)"
            }
        }
        
        # Extract errors and warnings from setuperr.log
        if (Test-Path $setupErrLog) {
            Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [DEBUG] - Extracting warnings and errors from '$setupErrLog'."
            Select-String -Path $setupErrLog -Pattern "Error", "Warning" | ForEach-Object {
                Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [DEBUG] - $($_.Line)"
            }
        }
    }

    exit 1
} else {
    Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [INFO] - The Windows 11 upgrade process completed successfully with exit code 0."
}

# Step 7: Clean up the installer
if (Test-Path $installerPath) {
    Remove-Item -Path $installerPath -Force
    Write-Output "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [INFO] - Cleaned up installer from '$installerPath'."
}

# Step 8: Exit with a success code
exit 0

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.

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

Frequently asked questions.

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.

Ready when you are.

No credit card. No sales call. Just sign up and start managing.