-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathW11_upgrade.ps1
137 lines (117 loc) · 5.64 KB
/
W11_upgrade.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# ==========================================
# PowerShell Script to Mount ISO, Upgrade Windows, and Clean Up
# ==========================================
# === Step 1: Define the Path to the ISO in C:\Temp ===
$IsoPath = "C:\Temp\Windows.iso"
# === Step 2: Verify that the ISO File Exists ===
if (-not (Test-Path -Path $IsoPath)) {
Write-Error "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - ISO file not found at path: $IsoPath"
exit 1
} else {
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - ISO file verified at path: $IsoPath"
}
# === Step 3: Mount the ISO and Retrieve Drive Letter ===
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Mounting the ISO: $IsoPath"
try {
$DiskImg = Mount-DiskImage -ImagePath $IsoPath -PassThru -ErrorAction Stop
Start-Sleep -Seconds 10 # Brief pause to ensure the ISO is fully mounted
$VolInfo = $DiskImg | Get-Volume
if (-not $VolInfo) {
throw "Failed to retrieve volume information for the mounted ISO."
}
$DriveLetter = ($VolInfo.DriveLetter + ":")
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - ISO mounted to drive letter: $DriveLetter"
} catch {
Write-Error "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Error mounting ISO: $_"
exit 1
}
# === Step 4: Path to the Setup Executable ===
$SetupPath = Join-Path -Path $DriveLetter -ChildPath "setup.exe"
# === Step 5: Verify that setup.exe Exists ===
if (-not (Test-Path -Path $SetupPath)) {
Write-Error "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - setup.exe not found at path: $SetupPath"
exit 1
} else {
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - setup.exe found at path: $SetupPath"
}
# === Step 6: Define the Upgrade Arguments ===
$Arguments = '/Auto Upgrade /Quiet /Telemetry Disable /Compat IgnoreWarning /ShowOOBE None /Eula Accept /NoReboot'
# === Step 7: Start the Upgrade Process ===
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Starting the Windows upgrade process..."
try {
# Start setup.exe directly and capture the process
$Process = Start-Process -FilePath $SetupPath -ArgumentList $Arguments -WindowStyle Hidden -PassThru -ErrorAction Stop
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Windows upgrade process initiated successfully with PID: $($Process.Id)"
} catch {
Write-Error "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Failed to start the upgrade process: $_"
exit 1
}
# === Step 8: Wait for the Upgrade Process to Complete ===
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Waiting for the upgrade process to complete..."
$CheckInterval = 60 # Check every 60 seconds
try {
while ($true) {
# Windows 11 Setup related process names to monitor
$Processes = @('setup', 'SetupHost', 'SetupPrep')
$RunningProcesses = $Processes | ForEach-Object {
Get-Process -Name $_ -ErrorAction SilentlyContinue
} | Where-Object { $_ -and -not $_.HasExited }
if ($RunningProcesses) {
foreach ($proc in $RunningProcesses) {
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - $($proc.Name) is still running."
}
Start-Sleep -Seconds $CheckInterval
} else {
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - All monitored processes have exited."
# Wait an additional minute to ensure everything is done
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Waiting an additional minute before cleanup..."
Start-Sleep -Seconds 60
break
}
}
} catch {
Write-Error "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Error while waiting for upgrade process: $_"
exit 1
}
# === Step 9: Perform Cleanup ===
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Starting cleanup process..."
# Unmount the ISO
try {
Dismount-DiskImage -ImagePath $IsoPath -ErrorAction Stop
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - ISO unmounted successfully."
} catch {
Write-Error "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Failed to unmount ISO: $_"
# Proceeding with deletion attempt
}
# Delete the ISO file
try {
Remove-Item -Path $IsoPath -Force -ErrorAction Stop
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - ISO file deleted successfully."
} catch {
Write-Error "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Failed to delete ISO file: $_"
}
# === Step 10: Reboot the System ===
Write-Host "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Preparing to reboot the system to complete the upgrade..."
try {
# Define the countdown time in seconds (5 minutes)
$countdown = 300
# Define the shutdown message for the system notification
$shutdownMessage = "The Windows 11 installation process is now complete. This system will reboot in five minutes to finish the upgrade. Please save your work."
# === Step 10a: Initiate System Reboot with Custom Message ===
Write-Host "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Initiating system reboot..."
try {
# Initiate a reboot with a 5-minute countdown, force applications to close, and include the custom message
shutdown.exe /r /t $countdown /c "$shutdownMessage" /f
Write-Host "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Reboot initiated successfully."
}
catch {
Write-Error "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Failed to initiate system reboot: $_"
exit 1
}
}
catch {
Write-Error "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - An unexpected error occurred: $_"
exit 1
}
# === Step 11: Script Ends Here ===
Write-Host "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Script execution completed. The system will reboot shortly to complete the upgrade."