-
Notifications
You must be signed in to change notification settings - Fork 0
/
export-wsl-distro.ps1
265 lines (155 loc) · 8.43 KB
/
export-wsl-distro.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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
function Check-IsElevated {
$id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$p = New-Object System.Security.Principal.WindowsPrincipal($id)
if ($p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Output $true
}
else {
Write-Output $false
}
}
# Define the function with a parameter for the process name to quit Docker Desktop
function StopProcessByName ($processName) {
# Check if the process is running
$process = Get-Process -Name $processName -ErrorAction SilentlyContinue
# If the process is running, stop it and display a message
if ($process) {
Stop-Process -Name $processName
Write-Host "`n [:::Information:::] The process $processName has been stopped" -ForegroundColor Blue -BackgroundColor Black
Start-Sleep -Seconds 10
} else {
# If the process is not running, display a message
Write-Host "`n [:::Information:::] The process $processName is not running" -ForegroundColor Blue -BackgroundColor Black
}
}
# Define the function to check for specific errors for Shutting down "Docker Desktop" and "WSL" and retry
function CheckErrorAndRetry {
# Define the command to shutdown WSL
$ShutdownWSL = "wsl --shutdown"
# Define the command to export the WSL distribution to a VHD file
# Use string interpolation to build the WSL export command
$wslExportCommand = "wsl --export $selectedDistro $exportPath --vhd"
Write-Host "`n [:::Action:::] Shutting down `"Docker Desktop`" ........." -ForegroundColor Magenta -BackgroundColor Black
# Call the function with the process name to quit Docker Desktop as an argument
StopProcessByName "Docker Desktop"
$StopProcessByName_Status = $?
Write-Host "`n [:::Action:::] Shutting down WSL ........." -ForegroundColor Magenta -BackgroundColor Black
Invoke-Expression $ShutdownWSL
$ShutdownWSL_Status = $?
Start-Sleep -Seconds 10
if ($ShutdownWSL_Status -and $StopProcessByName_Status ){
Write-Host "`n [:::Information:::] Exporting the selected WSL distro ........." -ForegroundColor Blue -BackgroundColor Black
$output = Invoke-Expression $wslExportCommand 2>&1
# Check for specific error conditions
if ($output -match "cannot access the file" -or $output -match "Error code" -or $output -match "used by another process") {
# -ForegroundColor White -BackgroundColor DarkMagenta
Write-Host "`n [:::Warning:::] $output" -ForegroundColor White -BackgroundColor DarkRed
# -ForegroundColor White -BackgroundColor DarkMagenta
Write-Host "`n [:::Warning:::] Failed to export WSL distribution. Please check the distribution name and export path." -ForegroundColor White -BackgroundColor DarkRed
return
}
}
}
# Define the function to start "Docker Desktop" process or service
function StartDockerDesktop {
Start-Process -FilePath "C:\Program Files\Docker\Docker\Docker Desktop.exe" -WindowStyle Normal
if ($?){
Write-Host "`n [:::Information:::] `"Docker Desktop`" start and run correctly." -ForegroundColor Blue -BackgroundColor Black
} else {
Write-Host "`n [:::Warning:::] `"Docker Desktop`" does not start and run correctly. Re-run starting `"Docker Desktop`" process." -ForegroundColor White -BackgroundColor DarkRed
StartDockerDesktop
Start-Sleep -Seconds 10
}
}
if (Check-IsElevated) {
################################################
# Preperation to export wsl distro to vhdx
################################################
# List down available WSL distros
$WSL_Distro_List = wsl -l -q | Where-Object { $_ -ne "" }
# Write-Host "`nAvailable WSL Distros:"
Write-Host "`n Available WSL Distros: `n" -ForegroundColor Yellow -BackgroundColor Black
$WSL_Distro_List | ForEach-Object { Write-Host " * $_ " -ForegroundColor Yellow -BackgroundColor Black }
$validDistro = $false
do {
$default_selectedDistro = "kali-linux"
# Prompt the user to choose a WSL distro
$selectedDistro = Read-Host "`n Enter the name of the distro you want to export or press `"Enter`" to use the default selected disro ( $default_selectedDistro )"
if ($selectedDistro -eq "") {
$selectedDistro = $default_selectedDistro
}
# Validate user input, must be from the list
if ($WSL_Distro_List -contains $selectedDistro) {
# Valid input, set $validDistro = $true and exit the loop
$validDistro = $true
break
}
else {
$validDistro = $false
# Invalid input, display an error message and repeat the loop
Write-Host "`n [:::Warning:::] Invalid distro choice. Please select a valid distro from the list." -ForegroundColor White -BackgroundColor DarkRed
}
}
while ($true)
# Display the selected distro to user
Write-Host "`n [:::Information:::] You have selected `"$selectedDistro`" WSL distro !" -ForegroundColor Blue -BackgroundColor Black
# Add Date variable with DDMMYYYY format
$Date = Get-Date -Format "ddMMyyyy-HHmm"
# Define the default path to be used to save the VHDX file
$defaultPath = "C:\Users\$env:UserName\Desktop"
# Prompt user to enter the path where the VHDX file will be saved
$exportPath = Read-Host -Prompt "`n Enter the path where you want to save the VHDX file or press `"Enter`" to use the default path ( $defaultPath )"
if ($exportPath -eq "") {
$exportPath = $defaultPath
}
Write-Host "`n [:::Information:::] The VHDX file will be saved at: `"$exportPath\$selectedDistro-$Date.vhdx`" " -ForegroundColor Blue -BackgroundColor Black
# Combine all the variable for exported path with the format of "exportPath\$selectedDistro-$Date.vhdx"
$exportPath = [System.IO.Path]::Combine($exportPath, "$selectedDistro-$Date.vhdx")
# Define the command to shutdown WSL
$ShutdownWSL = "wsl --shutdown"
# Define the command to export the WSL distribution to a VHD file
# Use string interpolation to build the WSL export command
$wslExportCommand = "wsl --export $selectedDistro $exportPath --vhd"
# Check if the chosen distro is in the list, if yes then run the function of CheckErrorAndRetry
if ($validDistro -eq $true) {
# Initial run of the command
CheckErrorAndRetry
$CheckErrorAndRetry_Status = $?
} else {
Write-Host "" -ForegroundColor White -BackgroundColor DarkRed
}
# Check if the function of CheckErrorAndRetry is running correctly, if not re-run it
$export_status = $false
# if ($CheckErrorAndRetry_Status = $?){
if ($CheckErrorAndRetry_Status -eq $true){
Start-Sleep -Seconds 10
if (Test-Path $exportPath) {
Write-Host "`n [:::Information:::] $exportPath exists." -ForegroundColor Blue -BackgroundColor Black
Write-Host "`n [:::Information:::] Exported $selectedDistro to $exportPath" -ForegroundColor Blue -BackgroundColor Black
Write-Host "`n [:::Information:::] Set `$export_status to `$true" -ForegroundColor Blue -BackgroundColor Black
$export_status = $true
} else {
Write-Host "`n [:::Warning:::] $exportPath does not exist." -ForegroundColor White -BackgroundColor DarkRed
Write-Host "`n [:::Warning:::] Re-run CheckErrorAndRetry." -ForegroundColor White -BackgroundColor DarkRed
$export_status = $false
CheckErrorAndRetry
}
} else {
Write-Host "`n [:::Warning:::] CheckErrorAndRetry_Status return failed and Re-run CheckErrorAndRetry." -ForegroundColor White -BackgroundColor DarkRed
Write-Host "`n [:::Information:::] Set `$export_status to `$false" -ForegroundColor Blue -BackgroundColor Black
$export_status = $false
CheckErrorAndRetry
}
# Check if the function of CheckErrorAndRetry is running correctly and the $export_status is set to $true
# Clean-up
if ($export_status = $true){
Start-Sleep -Seconds 10
Write-Host "`n [:::Information:::] Starting `"Docker Desktop`" process." -ForegroundColor Blue -BackgroundColor Black
StartDockerDesktop
}
}
else {
# prompt the user to use elevated powershell and exit the script
Write-Host "`n [:::Warning:::] Please run this script as Administrator.`n" -ForegroundColor Blue -BackgroundColor Black
exit
}