Windows 10 到 Windows 11 的自动化升级脚本

此PowerShell脚本的主要目的是自动化Windows 10系统的升级过程,简化用户操作,确保系统顺利过渡到Windows 11。脚本通过挂载指定的Windows 11 ISO镜像并启动升级进程,确保用户能够顺利完成升级。

1. 初始化变量

$Win11IsoPath = "定义windows 11 iso文件路径"
$MountPath = "$env:TEMP\Win11ISO"
$LogPath = "C:\Windows\Temp\Win11Upgrade.log"
$SetupExe = "$MountPath\setup.exe"
$TimeoutMinutes = 240  # 升级超时时间(分钟)
  • 变量定义:设置ISO文件路径、挂载路径、日志路径、安装程序路径和超时时间,便于后续使用。

2. 日志文件创建

if (!(Test-Path $LogPath)) {
    New-Item -ItemType File -Path $LogPath | Out-Null
}
  • 日志初始化:检查日志文件是否存在,如果不存在,则创建一个新的日志文件,以便于记录后续操作。

3. 日志记录函数

function Write-Log {
    param ([string]$Message, [string]$Level = "INFO")
    $TimeStamp = "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] [$Level] "
    $LogEntry = $TimeStamp + $Message
    $LogEntry | Out-File -Append $LogPath
    
    # 根据日志级别显示不同颜色
    switch ($Level) {
        "ERROR" { Write-Host $LogEntry -ForegroundColor Red }
        "WARNING" { Write-Host $LogEntry -ForegroundColor Yellow }
        "SUCCESS" { Write-Host $LogEntry -ForegroundColor Green }
        default { Write-Host $LogEntry }
    }
}
  • 功能:负责记录日志信息,包括时间戳、日志级别和消息内容。
  • 颜色输出:根据不同的日志级别,使用不同颜色输出到控制台,方便用户识别信息的紧急性。

4. 权限检查

function Test-Administrator {
    $user = [Security.Principal.WindowsIdentity]::GetCurrent()
    $principal = New-Object Security.Principal.WindowsPrincipal $user
    return $principal.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}

if (-not (Test-Administrator)) {
    Write-Log "错误: 请以管理员权限运行此脚本!" "ERROR"
    Exit 1
}
  • 管理员权限检查:确保脚本以管理员身份运行,如果没有权限则退出并提示用户,避免后续操作因权限不足而失败。

5. 系统版本检查

$osVersion = [Environment]::OSVersion.Version
if ($osVersion.Major -ne 10) {
    Write-Log "错误: 此脚本仅适用于 Windows 10 系统。当前系统版本: $($osVersion.ToString())" "ERROR"
    Exit 1
}
  • 版本确认:检查当前操作系统版本,确保脚本仅在Windows 10上运行。如果不是,记录错误并退出。

5. ISO文件检查

if (!(Test-Path $Win11IsoPath)) {
    Write-Log "错误: ISO 文件不存在: $Win11IsoPath" "ERROR"
    Exit 1
}
  • 文件存在性检查:确认指定的ISO文件是否存在,若不存在则记录错误并退出,防止后续操作失败。

6. 检查升级进程

$setupProcess = Get-Process -Name "setup" -ErrorAction SilentlyContinue
if ($setupProcess) {
    Write-Log "Windows 11 升级已在进行中。退出脚本。"
    Exit 0
}
  • 防止重复升级:检查是否已有升级进程在运行,若是,则退出脚本以避免冲突。

7. 挂载ISO镜像

Write-Log "正在挂载 ISO 镜像..."
Show-ProgressBar -Percent 5 -Status "准备中" -CurrentOperation "挂载 ISO 镜像"

try {
    if (Get-Command Mount-DiskImage -ErrorAction SilentlyContinue) {
        $isoDrive = Mount-DiskImage -ImagePath $Win11IsoPath -PassThru
        $volume = $isoDrive | Get-Volume
        $MountPath = $volume.DriveLetter + ":\\"
    } else {
        $MountPath = "$env:TEMP\Win11ISO"
        New-Item -ItemType Directory -Path $MountPath -Force | Out-Null
        & dism /Mount-Image /ImageFile:$Win11IsoPath /Index:1 /MountDir:$MountPath | Out-File -Append $LogPath
    }
    
    Write-Log "ISO 镜像已成功挂载到: $MountPath" "SUCCESS"
    Show-ProgressBar -Percent 10 -Status "准备中" -CurrentOperation "验证安装文件"
} catch {
    Write-Log "错误: 挂载 ISO 镜像失败: $_" "ERROR"
  • 挂载ISO:尝试使用 Mount-DiskImage 命令挂载ISO文件。若挂载失败,则尝试使用DISM命令进行挂载。
  • 错误处理:在挂载失败时,记录错误信息并进行后续处理。

8. 提取ISO内容(如果挂载失败)

try {
    Write-Log "尝试提取 ISO 内容到临时文件夹..."
    $MountPath = "$env:TEMP\Win11ISO"
    New-Item -ItemType Directory -Path $MountPath -Force | Out-Null
    
    if (Get-Command Expand-Archive -ErrorAction SilentlyContinue) {
        Expand-Archive -Path $Win11IsoPath -DestinationPath $MountPath -Force
    } else {
        $7ZipPath = "$env:ProgramFiles\7-Zip\7z.exe"
        if (Test-Path $7ZipPath) {
            & $7ZipPath x $Win11IsoPath -o"$MountPath" -y | Out-File -Append $LogPath
        } else {
            Write-Log "错误: 无法找到 7-Zip 或 Expand-Archive 命令。请确保已安装 7-Zip 或使用 Windows 10/11。" "ERROR"
            Exit 1
        }
    }
    
    Write-Log "ISO 内容已成功提取到: $MountPath" "SUCCESS"
} catch {
    Write-Log "错误: 提取 ISO 内容失败: $_" "ERROR"
    Exit 1
}
  • 提取内容:如果挂载失败,则尝试提取ISO内容到临时文件夹。支持使用 Expand-Archive 或 7-Zip 工具。
  • 错误处理:在提取失败时,记录错误并退出。

9. 检查setup.exe文件

$SetupExe = "$MountPath\setup.exe"
if (!(Test-Path $SetupExe)) {
    $SetupExe = "$MountPath\sources\setup.exe"  # 尝试sources子文件夹
}

if (!(Test-Path $SetupExe)) {
    Write-Log "错误: setup.exe 未找到 - $SetupExe" "ERROR"
    if ($isoDrive) {
        Dismount-DiskImage -ImagePath $Win11IsoPath
    }
    Exit 1
}
  • 文件检查:确保 setup.exe 存在于挂载或提取的路径中,若找不到则记录错误并退出。

10. 启动升级过程

Write-Log "开始 Windows 11 升级..." "SUCCESS"
Show-ProgressBar -Percent 15 -Status "开始升级" -CurrentOperation "启动安装程序"

try {
    $process = Start-Process -FilePath $SetupExe -ArgumentList "/auto upgrade /eula accept /compat ignorewarning" -PassThru
    Write-Log "升级进程已启动,进程 ID: $($process.Id)" "SUCCESS"
    Write-Log "请查看 Windows 11 安装界面获取详细进度!" "SUCCESS"
} catch {
    Write-Log "错误: 启动升级进程失败: $_" "ERROR"
    if ($isoDrive) {
        Dismount-DiskImage -ImagePath $Win11IsoPath
    }
    Exit 1
}
  • 启动升级:通过 Start-Process 启动升级程序,并传递必要的参数以自动接受EULA。
  • 错误处理:在启动失败时,记录错误信息并卸载ISO镜像。

10. 监控升级进程

$startTime = Get-Date
$lastStatusTime = $startTime
$consecutiveIdleMinutes = 0
$lastProgress = 20
$progressStages = @{
    20 = "正在准备升级..."
    30 = "正在检查系统兼容性..."
    40 = "正在下载更新文件..."
    50 = "正在准备安装..."
    60 = "正在安装 Windows 11..."
    70 = "正在配置系统设置..."
    80 = "正在安装功能和驱动程序..."
    90 = "正在完成安装..."
    95 = "准备重启以完成升级..."
}

Write-Log "开始监控升级进程,超时设置: $TimeoutMinutes 分钟"

while ($true) {
    $setupProcess = Get-Process -Name "setup" -ErrorAction SilentlyContinue
    
    if (!$setupProcess) {
        Write-Log "Windows 11 升级进程已退出。检查升级状态..."
        Show-ProgressBar -Percent 100 -Status "检查结果" -CurrentOperation "验证升级完成"
        break
    }
    ...
}
  • 进度监控:初始化时间和进度变量,使用 while 循环持续监控 setup.exe 进程,记录进度和状态。

11. 超时处理

if ($elapsedMinutes -ge $TimeoutMinutes) {
    Write-Log "警告: Windows 11 升级进程似乎挂起。尝试重启 setup.exe..." "WARNING"
    Show-ProgressBar -Percent $lastProgress -Status "警告" -CurrentOperation "升级超时,尝试重启"
    
    try {
        Stop-Process -Name "setup" -Force
        Write-Log "已终止挂起的升级进程。"
    } catch {
        Write-Log "错误: 终止挂起的升级进程失败: $_" "ERROR"
    }
    
    Start-Sleep -Seconds 10
    
    try {
        $process = Start-Process -FilePath $SetupExe -ArgumentList "/auto upgrade /eula accept /compat ignorewarning" -PassThru
        Write-Log "已重新启动升级进程,进程 ID: $($process.Id)" "SUCCESS"
    } catch {
        Write-Log "错误: 重新启动升级进程失败: $_" "ERROR"
        break
    }
}
  • 超时检测:如果升级过程超过设定的超时时间,尝试停止当前的 setup.exe 进程,并重新启动它。

12. 清理资源

try {
    if ($isoDrive) {
        Dismount-DiskImage -ImagePath $Win11IsoPath
        Write-Log "ISO 镜像已卸载。"
    } elseif (Test-Path $MountPath) {
        Remove-Item -Path $MountPath -Recurse -Force -ErrorAction SilentlyContinue
        Write-Log "临时文件夹已清理。"
    }
} catch {
    Write-Log "警告: 清理资源失败: $_" "WARNING"
}
  • 资源清理:在升级结束后,卸载ISO镜像并删除临时文件夹,确保系统资源得到释放。

13. 升级验证

try {
    $osVersion = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").ReleaseId
    $buildNumber = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").CurrentBuildNumber
    
    Write-Log "当前系统版本: $osVersion,内部版本: $buildNumber"
    
    if ([int]$buildNumber -ge 22000) {
        Write-Log "Windows 11 升级成功! 🎉" "SUCCESS"
        ...
    } else {
        Write-Log "错误: Windows 11 升级失败。请检查日志。" "ERROR"
        Exit 1
    }
} catch {
    Write-Log "错误: 检查升级状态失败: $_" "ERROR"
    Exit 1
}
  • 版本检查:获取当前操作系统版本和内部版本号,确认是否成功升级到Windows 11。如果成功,记录成功信息;如果失败,记录错误信息。

14. 系统重启

Write-Log "将在 30 秒后重启系统..."
Show-ProgressBar -Percent 100 -Status "完成" -CurrentOperation "系统将在30秒后重启"
...
Restart-Computer -Force
  • 重启提示:在确认升级成功后,提示用户系统将在30秒后重启,以完成安装。

15.Win11Upgrade_V1

<#
.SYNOPSIS
    Windows 10 自动升级到 Windows 11 脚本
.DESCRIPTION
    此脚本用于将 Windows 10 系统升级到 Windows 11。它会挂载指定的 Windows 11 ISO 镜像,并启动升级过程。
.PARAMETER Win11IsoPath
    指定 Windows 11 ISO 镜像的路径。
.AUTHOR
    ©LLH  <https://lilianhua.com>
.LICENSE
    This script is licensed under the GPL License.  
#>
###############################################################################
# Windows 10 自动升级到 Windows 11 完整可见版脚本
# 功能:
# 1. 自动挂载/提取 Windows 11 ISO 镜像
# 2. 强制显示升级界面,实时查看进度
# 3. 超时监控与自动重试
# 4. 详细日志记录与彩色输出
# 5. 自动重启验证
# 6. 若提示执行策略问题,先运行 Set-ExecutionPolicy Bypass -Scope Process -Force
###############################################################################

# 定义路径和变量
$Win11IsoPath = "iso文件路径"
$MountPath = "$env:TEMP\Win11ISO"
$LogPath = "C:\Windows\Temp\Win11Upgrade.log"
$SetupExe = "$MountPath\setup.exe"
$TimeoutMinutes = 240  # 升级超时时间(分钟)

# 创建日志文件(如果不存在)
if (!(Test-Path $LogPath)) {
    New-Item -ItemType File -Path $LogPath | Out-Null
}

# 记录日志函数
function Write-Log {
    param ([string]$Message, [string]$Level = "INFO")
    $TimeStamp = "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] [$Level] "
    $LogEntry = $TimeStamp + $Message
    $LogEntry | Out-File -Append $LogPath
    
    # 根据日志级别显示不同颜色
    switch ($Level) {
        "ERROR" { Write-Host $LogEntry -ForegroundColor Red }
        "WARNING" { Write-Host $LogEntry -ForegroundColor Yellow }
        "SUCCESS" { Write-Host $LogEntry -ForegroundColor Green }
        default { Write-Host $LogEntry }
    }
}

# 显示进度条函数
function Show-ProgressBar {
    param (
        [int]$Percent,
        [string]$Status,
        [string]$CurrentOperation
    )
    
    $ProgressBarLength = 50
    $FilledLength = [math]::Floor($Percent * $ProgressBarLength / 100)
    $EmptyLength = $ProgressBarLength - $FilledLength
    
    $ProgressBar = "[" + ("█" * $FilledLength) + (" " * $EmptyLength) + "]"
    $ProgressText = "{0,3}% | {1} | {2}" -f $Percent, $Status, $CurrentOperation
    
    Write-Host "`r$ProgressBar $ProgressText" -NoNewline
}

# 开始脚本
Write-Log "=== Windows 11 自动升级脚本启动 ==="
Write-Log "开始时间: $(Get-Date)"
Write-Log "使用的 ISO 镜像: $Win11IsoPath"

# 检查是否以管理员权限运行
function Test-Administrator {
    $user = [Security.Principal.WindowsIdentity]::GetCurrent()
    $principal = New-Object Security.Principal.WindowsPrincipal $user
    return $principal.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}

if (-not (Test-Administrator)) {
    Write-Log "错误: 请以管理员权限运行此脚本!" "ERROR"
    Exit 1
}

# 检查 Windows 版本(确保是 Windows 10)
$osVersion = [Environment]::OSVersion.Version
if ($osVersion.Major -ne 10) {
    Write-Log "错误: 此脚本仅适用于 Windows 10 系统。当前系统版本: $($osVersion.ToString())" "ERROR"
    Exit 1
}

# 检查 ISO 文件是否存在
if (!(Test-Path $Win11IsoPath)) {
    Write-Log "错误: ISO 文件不存在: $Win11IsoPath" "ERROR"
    Exit 1
}

# 检查升级是否已在进行中
$setupProcess = Get-Process -Name "setup" -ErrorAction SilentlyContinue
if ($setupProcess) {
    Write-Log "Windows 11 升级已在进行中。退出脚本。"
    Exit 0
}

# 挂载 ISO 镜像
Write-Log "正在挂载 ISO 镜像..."
Show-ProgressBar -Percent 5 -Status "准备中" -CurrentOperation "挂载 ISO 镜像"

try {
    # 检查是否已安装 Mount-DiskImage 命令(适用于 Windows 10/11)
    if (Get-Command Mount-DiskImage -ErrorAction SilentlyContinue) {
        $isoDrive = Mount-DiskImage -ImagePath $Win11IsoPath -PassThru
        $volume = $isoDrive | Get-Volume
        $MountPath = $volume.DriveLetter + ":\\"
    } else {
        # 对于较旧的 Windows 版本,使用 DISM 命令
        $MountPath = "$env:TEMP\Win11ISO"
        New-Item -ItemType Directory -Path $MountPath -Force | Out-Null
        & dism /Mount-Image /ImageFile:$Win11IsoPath /Index:1 /MountDir:$MountPath | Out-File -Append $LogPath
    }
    
    Write-Log "ISO 镜像已成功挂载到: $MountPath" "SUCCESS"
    Show-ProgressBar -Percent 10 -Status "准备中" -CurrentOperation "验证安装文件"
} catch {
    Write-Log "错误: 挂载 ISO 镜像失败: $_" "ERROR"
    
    # 尝试使用临时文件夹提取 ISO 内容
    try {
        Write-Log "尝试提取 ISO 内容到临时文件夹..."
        $MountPath = "$env:TEMP\Win11ISO"
        New-Item -ItemType Directory -Path $MountPath -Force | Out-Null
        
        # 使用 Expand-Archive 命令提取 ISO 内容
        if (Get-Command Expand-Archive -ErrorAction SilentlyContinue) {
            Expand-Archive -Path $Win11IsoPath -DestinationPath $MountPath -Force
        } else {
            # 对于没有 Expand-Archive 命令的系统,使用 7-Zip
            $7ZipPath = "$env:ProgramFiles\7-Zip\7z.exe"
            if (Test-Path $7ZipPath) {
                & $7ZipPath x $Win11IsoPath -o"$MountPath" -y | Out-File -Append $LogPath
            } else {
                Write-Log "错误: 无法找到 7-Zip 或 Expand-Archive 命令。请确保已安装 7-Zip 或使用 Windows 10/11。" "ERROR"
                Exit 1
            }
        }
        
        Write-Log "ISO 内容已成功提取到: $MountPath" "SUCCESS"
        Show-ProgressBar -Percent 10 -Status "准备中" -CurrentOperation "验证安装文件"
    } catch {
        Write-Log "错误: 提取 ISO 内容失败: $_" "ERROR"
        Exit 1
    }
}

# 确保 setup.exe 存在
$SetupExe = "$MountPath\setup.exe"
if (!(Test-Path $SetupExe)) {
    $SetupExe = "$MountPath\sources\setup.exe"  # 尝试sources子文件夹
}

if (!(Test-Path $SetupExe)) {
    Write-Log "错误: setup.exe 未找到 - $SetupExe" "ERROR"
    
    # 卸载 ISO 镜像(如果已挂载)
    if ($isoDrive) {
        Dismount-DiskImage -ImagePath $Win11IsoPath
    }
    
    Exit 1
}

# 开始升级过程(使用完全可见的参数)
Write-Log "开始 Windows 11 升级..." "SUCCESS"
Show-ProgressBar -Percent 15 -Status "开始升级" -CurrentOperation "启动安装程序"

try {
    # 使用不带/quiet参数的完整安装命令
    $process = Start-Process -FilePath $SetupExe -ArgumentList "/auto upgrade /eula accept /compat ignorewarning" -PassThru
    Write-Log "升级进程已启动,进程 ID: $($process.Id)" "SUCCESS"
    Write-Log "请查看 Windows 11 安装界面获取详细进度!" "SUCCESS"
    
    # 显示安装界面提示
    Write-Host "`n=====================================================================" -ForegroundColor Cyan
    Write-Host " Windows 11 安装界面将在几秒钟后显示" -ForegroundColor Cyan
    Write-Host " 请密切关注安装窗口中的进度指示" -ForegroundColor Cyan
    Write-Host "=====================================================================`n" -ForegroundColor Cyan
    
    Show-ProgressBar -Percent 20 -Status "进行中" -CurrentOperation "安装程序初始化"
} catch {
    Write-Log "错误: 启动升级进程失败: $_" "ERROR"
    
    # 卸载 ISO 镜像(如果已挂载)
    if ($isoDrive) {
        Dismount-DiskImage -ImagePath $Win11IsoPath
    }
    
    Exit 1
}

# 监控 setup.exe 进程并尝试获取升级进度
$startTime = Get-Date
$lastStatusTime = $startTime
$consecutiveIdleMinutes = 0
$lastProgress = 20
$progressStages = @{
    20 = "正在准备升级..."
    30 = "正在检查系统兼容性..."
    40 = "正在下载更新文件..."
    50 = "正在准备安装..."
    60 = "正在安装 Windows 11..."
    70 = "正在配置系统设置..."
    80 = "正在安装功能和驱动程序..."
    90 = "正在完成安装..."
    95 = "准备重启以完成升级..."
}

Write-Log "开始监控升级进程,超时设置: $TimeoutMinutes 分钟"

while ($true) {
    $setupProcess = Get-Process -Name "setup" -ErrorAction SilentlyContinue
    
    if (!$setupProcess) {
        Write-Log "Windows 11 升级进程已退出。检查升级状态..."
        Show-ProgressBar -Percent 100 -Status "检查结果" -CurrentOperation "验证升级完成"
        break
    }
    
    # 检查是否超时
    $elapsedMinutes = (New-TimeSpan -Start $startTime -End (Get-Date)).TotalMinutes
    if ($elapsedMinutes -ge $TimeoutMinutes) {
        Write-Log "警告: Windows 11 升级进程似乎挂起。尝试重启 setup.exe..." "WARNING"
        Show-ProgressBar -Percent $lastProgress -Status "警告" -CurrentOperation "升级超时,尝试重启"
        
        try {
            Stop-Process -Name "setup" -Force
            Write-Log "已终止挂起的升级进程。"
        } catch {
            Write-Log "错误: 终止挂起的升级进程失败: $_" "ERROR"
        }
        
        Start-Sleep -Seconds 10
        
        try {
            $process = Start-Process -FilePath $SetupExe -ArgumentList "/auto upgrade /eula accept /compat ignorewarning" -PassThru
            Write-Log "已重新启动升级进程,进程 ID: $($process.Id)" "SUCCESS"
            $startTime = Get-Date  # 重置计时器
            $lastStatusTime = $startTime
            $consecutiveIdleMinutes = 0
            Show-ProgressBar -Percent $lastProgress -Status "已重启" -CurrentOperation "继续升级"
        } catch {
            Write-Log "错误: 重新启动升级进程失败: $_" "ERROR"
            break
        }
    }
    
    # 检查升级进度(基于时间估算)
    $estimatedProgress = [math]::Min(95, 20 + [math]::Floor($elapsedMinutes * 75 / $TimeoutMinutes))
    
    # 更新进度显示
    if ($estimatedProgress -ge ($lastProgress + 5)) {
        $lastProgress = $estimatedProgress
        $currentStage = $progressStages.Get_Item([math]::Floor($lastProgress / 10) * 10)
        Show-ProgressBar -Percent $lastProgress -Status "进行中" -CurrentOperation $currentStage
    }
    
    # 每 15 分钟记录一次状态
    if ((New-TimeSpan -Start $lastStatusTime -End (Get-Date)).TotalMinutes -ge 15) {
        $currentStage = $progressStages.Get_Item([math]::Floor($lastProgress / 10) * 10)
        Write-Log "升级进程仍在运行,已运行时间: $([math]::Round($elapsedMinutes, 2)) 分钟,估计进度: $lastProgress%,当前阶段: $currentStage"
        $lastStatusTime = Get-Date
    }
    
    Start-Sleep -Seconds 30  # 每30秒检查一次
}

# 卸载 ISO 镜像或清理临时文件夹
try {
    if ($isoDrive) {
        Dismount-DiskImage -ImagePath $Win11IsoPath
        Write-Log "ISO 镜像已卸载。"
    } elseif (Test-Path $MountPath) {
        Remove-Item -Path $MountPath -Recurse -Force -ErrorAction SilentlyContinue
        Write-Log "临时文件夹已清理。"
    }
} catch {
    Write-Log "警告: 清理资源失败: $_" "WARNING"
}

# 确保升级成功
try {
    $osVersion = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").ReleaseId
    $buildNumber = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").CurrentBuildNumber
    
    Write-Log "当前系统版本: $osVersion,内部版本: $buildNumber"
    
    if ([int]$buildNumber -ge 22000) {
        Write-Log "Windows 11 升级成功! 🎉" "SUCCESS"
        Show-ProgressBar -Percent 100 -Status "成功" -CurrentOperation "Windows 11 已安装"
        
        # 清理临时文件
        try {
            if (Test-Path $MountPath) {
                Remove-Item -Path $MountPath -Recurse -Force -ErrorAction SilentlyContinue
            }
            Write-Log "临时文件已删除。"
        } catch {
            Write-Log "警告: 清理临时文件失败: $_" "WARNING"
        }
        
        # 安排系统重启
        Write-Log "将在 30 秒后重启系统..."
        Show-ProgressBar -Percent 100 -Status "完成" -CurrentOperation "系统将在30秒后重启"
        
        for ($i = 30; $i -gt 0; $i--) {
            Write-Host "`r系统将在 $i 秒后重启。按 Ctrl+C 取消重启..." -NoNewline
            Start-Sleep -Seconds 1
        }
        
        Write-Host "`n"
        Restart-Computer -Force
    } else {
        Write-Log "错误: Windows 11 升级失败。请检查日志。" "ERROR"
        Show-ProgressBar -Percent 100 -Status "失败" -CurrentOperation "升级未完成,请查看日志"
        Exit 1
    }
} catch {
    Write-Log "错误: 检查升级状态失败: $_" "ERROR"
    Show-ProgressBar -Percent 100 -Status "错误" -CurrentOperation "无法验证升级结果"
    Exit 1
}    

16.Win11Upgrade_V2

<#
.SYNOPSIS
    Windows 10 自动升级到 Windows 11 脚本
.DESCRIPTION
    此脚本用于将 Windows 10 系统升级到 Windows 11。它会挂载指定的 Windows 11 ISO 镜像,并启动升级过程。
.PARAMETER Win11IsoPath
    指定 Windows 11 ISO 镜像的路径。
.AUTHOR
    ©LLH  <https://lilianhua.com>
.LICENSE
    This script is licensed under the GPL License.  
#>
###############################################################################
# Windows 10 自动升级到 Windows 11 完整可见版脚本
# 功能:
# 1. 自动挂载/提取 Windows 11 ISO 镜像
# 2. 强制显示升级界面,实时查看进度
# 3. 超时监控与自动重试
# 4. 详细日志记录与彩色输出
# 5. 自动重启验证
# 6. 若提示执行策略问题,先运行 Set-ExecutionPolicy Bypass -Scope Process -Force
###############################################################################

### 配置区域(仅需修改此处)###
$Win11IsoPath = "填写网络或本地路径"  # ISO 网络路径
$LogPath      = "C:\Windows\Temp\Win11Upgrade.log"                               # 日志文件路径
$TimeoutMinutes = 240                                                           # 升级超时时间(分钟)
$MountPath    = "$env:TEMP\Win11Mount"                                          # ISO 挂载/提取临时路径
################################

### 日志函数(带颜色区分)###
function Write-Log {
    param(
        [string]$Message, 
        [string]$Level = "INFO"  # 可选:INFO, SUCCESS, WARNING, ERROR
    )
    $TimeStamp = "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] [$Level] "
    $LogEntry  = $TimeStamp + $Message
    $LogEntry | Out-File -Append $LogPath  # 写入日志文件
    
    # 控制台彩色输出
    switch ($Level) {
        "ERROR"   { Write-Host $LogEntry -ForegroundColor Red }
        "WARNING" { Write-Host $LogEntry -ForegroundColor Yellow }
        "SUCCESS" { Write-Host $LogEntry -ForegroundColor Green }
        default   { Write-Host $LogEntry }
    }
}

### 1. 管理员权限检查 ###
$isAdmin = ([Security.Principal.WindowsPrincipal]::new(
    [Security.Principal.WindowsIdentity]::GetCurrent()
)).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

if (-not $isAdmin) {
    Write-Log "错误:必须以管理员身份运行此脚本!" "ERROR"
    Exit 1
}

### 2. Windows 版本检查(仅支持 Win10)###
$osVersion = [Environment]::OSVersion.Version
if ($osVersion.Major -ne 10) {
    Write-Log "错误:仅支持 Windows 10 系统,当前系统版本:$($osVersion.ToString())" "ERROR"
    Exit 1
}

### 3. ISO 文件存在性检查 ###
if (-not (Test-Path $Win11IsoPath)) {
    Write-Log "错误:ISO 文件不存在:$Win11IsoPath" "ERROR"
    Exit 1
}

### 4. 挂载/提取 ISO 镜像 ###
$diskImage = $null  # 记录挂载的磁盘镜像对象,用于后续卸载
try {
    Write-Log "开始处理 ISO 镜像(挂载/提取)..."
    
    # 优先使用 Mount-DiskImage(Windows 10/11 原生支持)
    if (Get-Command Mount-DiskImage -ErrorAction SilentlyContinue) {
        $diskImage = Mount-DiskImage -ImagePath $Win11IsoPath -PassThru
        $volume    = $diskImage | Get-Volume
        $MountPath = "$($volume.DriveLetter):\"
        Write-Log "ISO 已成功挂载到:$MountPath" "SUCCESS"
    } 
    # 备用方案:提取 ISO 到临时文件夹(需 7-Zip 或 Expand-Archive)
    else {
        # 创建临时文件夹
        if (-not (Test-Path $MountPath)) {
            New-Item -ItemType Directory -Path $MountPath -Force | Out-Null
        }
        
        # 尝试使用系统内置的 Expand-Archive(Win10+ 支持)
        if (Get-Command Expand-Archive -ErrorAction SilentlyContinue) {
            Write-Log "使用 Expand-Archive 提取 ISO 到:$MountPath" "INFO"
            Expand-Archive -Path $Win11IsoPath -DestinationPath $MountPath -Force
        } 
        #  fallback:使用 7-Zip(需提前安装)
        else {
            $7ZipPath = "$env:ProgramFiles\7-Zip\7z.exe"
            if (Test-Path $7ZipPath) {
                Write-Log "使用 7-Zip 提取 ISO 到:$MountPath" "INFO"
                & $7ZipPath x $Win11IsoPath -o"$MountPath" -y | Out-File -Append $LogPath
            } else {
                Write-Log "错误:未找到 Mount-DiskImage、Expand-Archive 或 7-Zip,无法处理 ISO!" "ERROR"
                Exit 1
            }
        }
        Write-Log "ISO 已成功提取到:$MountPath" "SUCCESS"
    }
} catch {
    Write-Log "错误:挂载/提取 ISO 失败:$_" "ERROR"
    Exit 1
}

### 5. 定位 setup.exe ###
$SetupExe = "$MountPath\sources\setup.exe"  # 优先检查 sources 文件夹
if (-not (Test-Path $SetupExe)) {
    $SetupExe = "$MountPath\setup.exe"       # 备用路径
    if (-not (Test-Path $SetupExe)) {
        Write-Log "错误:未找到 setup.exe,路径:$SetupExe" "ERROR"
        # 清理资源
        if (Test-Path $MountPath) { Remove-Item -Path $MountPath -Recurse -Force -ErrorAction SilentlyContinue }
        if ($diskImage) { Dismount-DiskImage -ImagePath $Win11IsoPath -ErrorAction SilentlyContinue }
        Exit 1
    }
}

### 6. 启动 Windows 11 安装程序(强制显示界面)###
Write-Log "即将启动 Windows 11 安装程序,准备查看升级界面..." "INFO"
Write-Host @"

┌──────────────────────────────────────────────┐
│  🚨  Windows 11 安装窗口即将弹出!          │
│  📌  请切换到新窗口观察实时进度条!         │
│  ⏳  若长时间无响应,可按 Ctrl+C 终止重试!  │
└──────────────────────────────────────────────┘
"@ -ForegroundColor Cyan

try {
    # 关键参数:
    # /auto upgrade       - 自动升级模式
    # /eula accept        - 自动接受协议
    # /compat ignorewarning - 忽略兼容性警告
    # /noreboot           - 暂不自动重启(脚本后续控制)
    # -WindowStyle Normal - 强制显示安装窗口
    $process = Start-Process -FilePath $SetupExe -ArgumentList @(
        "/auto", "upgrade",
        "/eula", "accept",
        "/compat", "ignorewarning",
        "/noreboot"
    ) -PassThru -WindowStyle Normal
    
    Write-Log "安装进程已启动,PID:$($process.Id)" "SUCCESS"
} catch {
    Write-Log "错误:启动安装程序失败:$_" "ERROR"
    # 清理资源
    if (Test-Path $MountPath) { Remove-Item -Path $MountPath -Recurse -Force -ErrorAction SilentlyContinue }
    if ($diskImage) { Dismount-DiskImage -ImagePath $Win11IsoPath -ErrorAction SilentlyContinue }
    Exit 1
}

### 7. 监控安装进程(超时检测 + 进度提示)###
$startTime = Get-Date
while ($true) {
    # 检查进程是否存活
    if (-not (Get-Process -Id $process.Id -ErrorAction SilentlyContinue)) {
        Write-Log "安装进程已退出,开始验证升级结果..." "INFO"
        break
    }
    
    # 检查超时
    $elapsedMinutes = (New-TimeSpan -Start $startTime -End (Get-Date)).TotalMinutes
    if ($elapsedMinutes -ge $TimeoutMinutes) {
        Write-Log "警告:安装进程超时(已运行 $elapsedMinutes 分钟,超过 $TimeoutMinutes 分钟),尝试重启..." "WARNING"
        
        # 终止当前进程
        try {
            Stop-Process -Id $process.Id -Force -ErrorAction SilentlyContinue
            Write-Log "已终止超时的安装进程" "INFO"
        } catch {
            Write-Log "错误:终止安装进程失败:$_" "ERROR"
        }
        
        Start-Sleep -Seconds 10  # 等待资源释放
        
        # 重新启动安装
        try {
            $process = Start-Process -FilePath $SetupExe -ArgumentList @(
                "/auto", "upgrade",
                "/eula", "accept",
                "/compat", "ignorewarning",
                "/noreboot"
            ) -PassThru -WindowStyle Normal
            Write-Log "已重新启动安装进程,PID:$($process.Id)" "SUCCESS"
            $startTime = Get-Date  # 重置计时器
        } catch {
            Write-Log "错误:重新启动安装进程失败:$_" "ERROR"
            break
        }
    }
    
    # 实时进度提示(简单方式)
    Write-Host "`r安装进行中... 已运行 $([int]$elapsedMinutes) 分钟(按 Ctrl+C 终止)" -NoNewline
    Start-Sleep -Seconds 1
}

### 8. 验证升级结果 ###
try {
    $osBuild = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").CurrentBuildNumber
    if ([int]$osBuild -ge 22000) {
        Write-Log "Windows 11 升级成功!当前内部版本:$osBuild" "SUCCESS"
        Write-Host "`n🎉 升级成功!30 秒后自动重启系统..." -ForegroundColor Green
        
        # 30 秒倒计时提示
        for ($i = 30; $i -gt 0; $i--) {
            Write-Host "`r⏳ 系统将在 $i 秒后重启(按 Ctrl+C 取消)..." -NoNewline
            Start-Sleep -Seconds 1
        }
        
        Write-Host "`n"
        Restart-Computer -Force  # 强制重启
    } else {
        Write-Log "错误:升级失败,当前系统内部版本:$osBuild(需 ≥ 22000)" "ERROR"
        Write-Host "`n❌ 升级失败,请查看日志:$LogPath" -ForegroundColor Red
    }
} catch {
    Write-Log "错误:检查系统版本失败:$_" "ERROR"
    Write-Host "`n❌ 检查升级结果失败,请查看日志:$LogPath" -ForegroundColor Red
} finally {
    # 清理临时资源
    if (Test-Path $MountPath) {
        Remove-Item -Path $MountPath -Recurse -Force -ErrorAction SilentlyContinue
        Write-Log "已清理临时文件夹:$MountPath" "INFO"
    }
    if ($diskImage) {
        Dismount-DiskImage -ImagePath $Win11IsoPath -ErrorAction SilentlyContinue
        Write-Log "已卸载 ISO 镜像" "INFO"
    }
}

17.命令执行

powershell.exe -ExecutionPolicy Bypass -File "Win11Upgrade_v1.ps1"
部分作用
powershell.exe启动 PowerShell 进程
-ExecutionPolicy Bypass临时绕过 PowerShell 的执行策略(仅对当前进程有效),允许运行脚本
-File "Win11Upgrade_v1.ps1"指定要运行的脚本文件(Win11Upgrade_v1.ps1)

执行后的效果

  • 命令会启动 PowerShell 进程,绕过执行策略,直接运行 Win11Upgrade_v1.ps1 脚本。
  • 脚本会按照之前的逻辑执行:挂载 ISO、检查环境、启动升级流程,并显示进度。