-
Notifications
You must be signed in to change notification settings - Fork 149
/
move-wsl.ps1
119 lines (102 loc) · 3.51 KB
/
move-wsl.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
Set-StrictMode -Version latest;
function Cleanup()
{
# Remove temporary file
Write-Host "Cleaning up ...";
Remove-Item -ErrorAction Ignore $tempFile;
}
# function to get distros
function Get-Distros()
{
# wsl seems to output Unicode always. When parsing results in PowerShell it will try to convert
# to Unicode strings (again) assuming it's in the Console.OutputEncoding code page (437 in my case).
# This causes incorrect results. We are forcing Console.OutputEncoding to be Unicode here
# to avoid the unnecessary conversion.
$consoleEncoding = [Console]::OutputEncoding;
[Console]::OutputEncoding = [System.Text.Encoding]::Unicode;
$result = wsl -l -v | ConvertFrom-String -PropertyNames SELECTED, NAME, STATE, VERSION | Select-Object -Skip 1;
[Console]::OutputEncoding = $consoleEncoding;
return $result;
}
# get and make sure there are distros
Write-Host 'Getting distros...';
$distros = @(Get-Distros);
$distroList = @($distros | ForEach-Object { $_.NAME });
if ($distroList.Length -le 0)
{
Write-Error 'No distro found';
Exit 1;
}
# prompt and get the distro to move
Write-Host "Select distro to move:";
$id = 0;
$distroList | ForEach-Object { Write-Host "$($id+1): $($distroList[$id])" -ForegroundColor Yellow; $id++; }
$selected = [int](Read-Host);
if (($selected -gt $distroList.Length) -or ($selected -le 0))
{
Write-Error "Invalid selection. Select a distro from 1 to $($distroList.Length)";
Exit 1;
}
$distro = $distroList[$selected - 1];
# get target directory
Write-Host 'Enter WSL target directory:';
$targetFolder = Read-Host;
# check if the target folder is the root of a drive
if ($targetFolder.Length -le 3 -and $targetFolder.EndsWith(':\'))
{
Write-Error 'Target folder cannot be root of a drive';
Exit 1;
}
$targetFolder = $targetFolder.trimend('\');
# confirm
$confirm = Read-Host "Move $($distro) to `"$($targetFolder)`"? (Y|n)";
if ($confirm -ne 'Y')
{
Write-Error 'User canceled';
Exit 1;
}
# Create target dir if non existent
if (-not(Test-Path $targetFolder))
{
New-Item -Path $targetFolder -ItemType 'directory' | Out-Null;
if (-not($?))
{
Write-Error "Failed to create target folder `"$($targetFolder)`"";
Exit 1;
}
} elseif (Test-Path (-join($targetFolder, "\ext4.vhdx")))
{
Write-Error "Target folder already contains an ext4.vhdx file that will get overwritten. Aborting.";
Exit 1;
}
# Export WSL image to tar file
$tempFile = Join-Path $targetFolder "$($distro).tar";
Write-Host "Exporting VHDX to `"$($tempFile)`" ...";
& cmd /c wsl --export $distro "`"$tempFile`"";
if (-not($? -and (Test-Path $tempFile -PathType Leaf)))
{
Write-Error "ERROR: Export failed";
Cleanup;
Exit 2;
}
# Unregister WSL so we can register it again at new location
Write-Host "Unregistering WSL ..."
& cmd /c wsl --unregister $distro | Out-Null
# Importing WSL at new location
Write-Host "Importing $distro from $targetFolder..."
& cmd /c wsl --import $distro $targetFolder "`"$tempFile`"" --version $distros[$selected -1].VERSION;
# Validating
$newDistros = @(Get-Distros);
$newDistroList = @($newDistros | ForEach-Object { $_.NAME });
if ($newDistroList -notcontains $distro)
{
Write-Error "Import failed. Distro not found. Export file at $tempFile";
Exit 3;
}
if (-not(Test-Path "$($targetFolder)\ext4.vhdx") -And -not(Test-Path "$($targetFolder)\rootfs"))
{
Write-Error "ERROR: Import failed. Target file/folder not found. Export file at $tempFile";
Exit 4;
}
Cleanup;
Write-Host "Done!" -ForegroundColor Green;