GithubHelp home page GithubHelp logo

pxlrbt / move-wsl Goto Github PK

View Code? Open in Web Editor NEW
1.4K 22.0 146.0 114 KB

Easily move your WSL distros VHDX file to a new location.

License: GNU General Public License v3.0

PowerShell 100.00%
wsl2 wsl bash-script batch-script powershell-script maintainer-wanted windows powershell

move-wsl's Introduction

Warning

As I switched the OS, I am not updating this script or fixing bugs anymore.
Have a look at the issue tab for some known issues.
Happy to merge PRs with fixes.

Move WSL

PowerShell script to move WSL 1 and WSL 2 distros VHDX file to a different location.

Interactive Example

Usage

Warning

This script uses official wsl commands and was used by a lot of people. Nevertheless some people had weird issues that resulted in broken WSL disks. Make sure you have a backup of your data, so you can restore in case of an error.

Interactive way of moving wsl for Windows PowerShell.

  1. ./move-wsl.ps1
  2. Select your distro
  3. Enter your target (i.e. D:\wsl target\ubuntu)

Moving Docker WSL

Before moving Docker WSL make sure to stop the Docker service. Otherwise Docker will crash and you may need to reset it to factory defaults.

FAQ

Default user was switched to root when moving a distro

Set your default user inside your distro by adding the following configuration to your /etc/wsl.conf.

[user]
default=YOUR_USERNAME

If the file doesn't exist create it manually. Then exit your distro, terminate it (wsl -t YOUR_DISTRO) and start it again. For further options see Microsoft Docs.

Some distributions also allow settings the default user via command line with YOUR_DISTRO config --default-user YOUR_USER (e.g. ubuntu config --default-user johndoe). Make sure to shutdown your distro before (wsl -t YOUR_DISTRO).

Standard distro switched when moving it

Since we need to unregister to import it with the same name, the standard distro can be switched. Just set your standard distro again:

wsl -s YOUR_DISTRO

WSL version was switched when moving distro

On import the distro will be registered with the current default WSL version. You can set your default WSL version with wsl --set-default-version <Version>. When the WSL version was accidentally changed while moving, you can set the version with wsl --set-version <Distro> <Version>.

move-wsl's People

Contributors

mystery-e204 avatar pxlrbt avatar sayakmukhopadhyay avatar schop0 avatar sidecus avatar slycordinator avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

move-wsl's Issues

The process cannot access the file because it is being used by another process

Describe the bug

After this:
image

There was E:\wsl\ext4.vhdx
When I issued wsl, a window flashed out and I could not get into ubuntu.
I issued wsl --list --verbose and could find ubuntu, but its state was "stop".

Then I try wsl --unregister Ubuntu

Now wsl --list shows nothing, but E:\wsl\ext4.vhdx is still there.
How can I use the E:\wsl\ext4.vhdx? I have important files in that ubuntu distro

In pwsh.exe:

PS C:\Users\MeMeMe> wsl --import Ubuntu E:\wsl E:\wsl\ext4.vhdx
The process cannot access the file because it is being used by another process

Execute fail when you has just one distro

Describe the bug
A clear and concise description of what the bug is.
When one distro, variable distroList seems can not parse success.
Please add terminal output if possible:
Getting distros...
Select distro to move:
1: U
1
Enter WSL target directory:
D:\Ubuntu
Move U to "D:\Ubuntu"? (Y|n): y
Exporting VHDX to "D:\Ubuntu\U.tar" ...
There is no distribution with the supplied name.
Error code: Wsl/Service/WSL_E_DISTRO_NOT_FOUND
D:\Downloads\move-wsl-1.4.0\move-wsl-1.4.0\move-wsl.ps1 : ERROR: Export failed
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,move-wsl.ps1

Cleaning up ...

Add wsl --shutdown to script?

Hi

just wondering if there's a reason that the script doesn't just add the wsl --shutdown before proceeding with the rest, to make sure it is shutdown, both for conversation and for the forgetful, since the point of the script is to automate things anyway?

WSL 2 distro is imported as WSL 1

Describe the bug
First of all - great job on the script, it makes moving distros way easier.

As for the issue - on older Windows versions (< 20150, where WSL 2 is not the default), WSL 2 distros are imported as WSL 1. I guess for newer Windows version the same issue happens the other way -> WSL 1 distros are imported as WSL 2.

It's easy to fix it using wsl --set-version, however I had a fairly heavy docker-desktop-data image which conversion took about 3 hours. I guess it'd be better to import it in the correct version.

According to:

    --import <Distro> <InstallLocation> <FileName> [Options]
        Imports the specified tar file as a new distribution.
        The filename can be - for standard input.

        Options:
            --version <Version>
                Specifies the version to use for the new distribution.

it can be set using the --version flag (https://github.com/pxlrbt/move-wsl/blob/master/move-wsl#L64). Perhaps the WSL version can be extracted at start when selecting which distro should be moved?

Script version:

  • [ x] Bash
  • [ x] Powershell
  • [ x] Batch

Import failed. Distro not found.

Using powershell, I tried to move Distro Ubuntu-20.04 from my HDD (E) to SSD (C).
But the importing was failed with this error message.

Enter WSL target directory:
C:\Users\erick\wsl
Move Ubuntu-20.04 to "C:\Users\erick\wsl"? (Y|n): Y
Exporting VHDX to "C:\Users\erick\wsl\Ubuntu-20.04.tar" ...
Unregistering WSL ...
Importing Ubuntu-20.04 from C:\Users\erick\wsl...
Unspecified error
E:\move-wsl.ps1 : Import failed. Distro not found. Export file at C:\Users\erick\wsl\Ubuntu-20.04.tar
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,move-wsl.ps1

Then I tried to run again the script. But I couldn't see Ubuntu-20.04 again.
Need help, what happens to all my datas in Distro Ubuntu-20.04?
I can see the files Ubuntu-20.04.tar in target directory with size 28GB.

Did I do something wrong?

Powershell Script Fails to Import

When I ran the powershell script it failed to import the tar file into WSL.

I believe this line is incorrect:

& cmd /c wsl --import $distro $targetFolder "`"$tempFile`"";

It looks like the backticks and quotation marks are not matched correctly (and I'm not comfortable enough with powershell to figure out the correct matching).

DISTRO_NOT_FOUND error (possibly because of wrong distro name detected)

Describe the bug
I used wsl --install to install a Ubuntu distro. However, when I run the ./move-wsl.ps1 script, the distro name it displayed is just "U", and when I moved to next steps, it will raise an Export Failed error with the error code "Wsl/Service/WSL_E_DISTRO_NOT_FOUND"

Please add terminal output if possible:
PS D:\Program Files\move-wsl> ./move-wsl.ps1
Getting distros...
Select distro to move:
1: U
1
Enter WSL target directory:
E:\WSL_Ubuntu
Move U to "E:\WSL_Ubuntu"? (Y|n): y
Exporting VHDX to "E:\WSL_Ubuntu\U.tar" ...
There is no distro with the provided name.
Error code: Wsl/Service/WSL_E_DISTRO_NOT_FOUND
D:\Program Files\move-wsl\move-wsl.ps1 : ERROR: Export failed
所在位置 行:1 字符: 1

  • ./move-wsl.ps1
  •   + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
      + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,move-wsl.ps1
    
    

Cleaning up ...

Default user switch

Describe the bug
I tried to change the default username back to the old username, which did not work with the instructions in the readme. But what worked is in Powershell the command <DistributionName> config --default-user <username>.

Example: ubuntu config --default-user johndoe

Of course you should shutdown WSL before that - wsl --shutdown

I found it easier than creating a config file and putting the username there. Maybe you could change that in the readme.

Deletes temp file w/o verifying import

I had the unfortunate experience of using this script and it deleted install and temp file. Argh! I think this was because I got Access Denied on the export, but it still went ahead on the full steps. It should check to see that the export was successful before deleting everything.

The supplied install location is already in use.

Describe the bug
Awesome job on the script!

The issue is as follows, when you import another distro in the same folder wsl --import will fail and report:

...
The supplied install location is already in use.

This is after the distro is already unregistered.

Please add terminal output if possible:

Move Debian to "C:\..\backup"? (Y|n): y
Exporting VHDX to "C:\..\backup\Debian.tar" ...
Unregistering WSL ...
Importing Debian from C:\..\backup...
The supplied install location is already in use.

Makes total sense since there is already an ext4.vhdx in the folder, maybe that can be checked before execution?

Script version:

  • Bash
  • Powershell
  • Batch

[Feature Request] Rename the new location

Before discovering this script, I've done some moves manually.

While doing this, I've taken up the system of leaving the base image in place, copying the export and importing it under a different name.

Like _001, _002, etc...

If I screw an image up, that means I can just copy the base image again.

With this script, it just gets moved and if I screw things up, I have to start all over.

Registry details not preserved during distro export/import...

Bug
WSL stores information about distros in the registry under HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lxss\{your-distro-uuid}; however, wsl --import and wsl --export do not save/restore these keys. Can move-wsl preserve this information?

Example
After running the command line

wsl --export Alpine - | wsl --import Alpine1 e:\wsl\Alpine1 -

to quickly copy the Alpine distro, the new registry entry for the Alpine1 copy has only a minimal set of keys and its DefaultUid has been changed to 0 (root):

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lxss\{your-alpine1-disto-uuid}]
"State"=dword:00000001
"DistributionName"="Alpine1"
"Version"=dword:00000002
"BasePath"="\\\\?\\E:\\wsl\\Alpine1"
"Flags"=dword:00000007
"DefaultUid"=dword:00000000

The original Alpine distro has more details including a KernelCommandLine and DefaultEnvironment as well as DefaultUid=dword:000003e8 (1000) (regular user):

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lxss\{your-alpine-distro-uuid}]
"State"=dword:00000001
"DistributionName"="Alpine"
"Version"=dword:00000001
"BasePath"="C:\\Users\\YourUserName\\AppData\\Local\\Packages\\36828agowa338.AlpineWSL_my43bytk1c4nr\\LocalState"
"Flags"=dword:00000007
"DefaultUid"=dword:000003e8
"PackageFamilyName"="36828agowa338.AlpineWSL_my43bytk1c4nr"
"KernelCommandLine"="BOOT_IMAGE=/kernel init=/init"
"DefaultEnvironment"=hex(7):48,00,4f,00,53,00,54,00,54,00,59,00,50,00,45,00,3d,\
  00,78,00,38,00,36,00,5f,00,36,00,34,00,00,00,4c,00,41,00,4e,00,47,00,3d,00,\
  65,00,6e,00,5f,00,55,00,53,00,2e,00,55,00,54,00,46,00,2d,00,38,00,00,00,50,\
  00,41,00,54,00,48,00,3d,00,2f,00,75,00,73,00,72,00,2f,00,6c,00,6f,00,63,00,\
  61,00,6c,00,2f,00,73,00,62,00,69,00,6e,00,3a,00,2f,00,75,00,73,00,72,00,2f,\
  00,6c,00,6f,00,63,00,61,00,6c,00,2f,00,62,00,69,00,6e,00,3a,00,2f,00,75,00,\
  73,00,72,00,2f,00,73,00,62,00,69,00,6e,00,3a,00,2f,00,75,00,73,00,72,00,2f,\
  00,62,00,69,00,6e,00,3a,00,2f,00,73,00,62,00,69,00,6e,00,3a,00,2f,00,62,00,\
  69,00,6e,00,3a,00,2f,00,75,00,73,00,72,00,2f,00,67,00,61,00,6d,00,65,00,73,\
  00,3a,00,2f,00,75,00,73,00,72,00,2f,00,6c,00,6f,00,63,00,61,00,6c,00,2f,00,\
  67,00,61,00,6d,00,65,00,73,00,00,00,54,00,45,00,52,00,4d,00,3d,00,78,00,74,\
  00,65,00,72,00,6d,00,2d,00,32,00,35,00,36,00,63,00,6f,00,6c,00,6f,00,72,00,\
  00,00,00,00

--
ASCII version of DefaultEnvironment:
HOSTTYPE=x86_64
LANG=en_US.UTF-8
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
TERM=xterm-256color

Issue #3974 from the microsoft/WSL repository has more details about how to workaround this issue in Powershell.

Script version:

  • [ x ] Bash
  • [ x ] Powershell
  • [ x ] Batch

Edit: How to find values
These commands provide values for DefaultUid, KernelCommandLine, and DefaultEnvironment:

@echo off
SET WSL_NAME=%~1
wsl -d %WSL_NAME% -e id -u
wsl -d %WSL_NAME% -e cat /proc/cmdline
wsl -d %WSL_NAME% sh -c "env |  grep -v -E '^(PATH|NAME|HOME|USER|LOGNAME|SHELL|WSL_DISTRO_NAME|WSLENV|WT_SESSION|WT_PROFILE_ID|SHLVL|PWD|DSISPLAY|WSL_INTEROP|DISPLAY|WAYLAND_DISPLAY|PULSE_SERVER|_)='"
echo|set /p ="PATH="
wsl -d %WSL_NAME% sh -c "printenv PATH | sed 's/:\/mnt\/.*//g'"

Cannot chose Distro in Interactive Mode

I have only one distro and it just treats (Default) as part of a name, so I needed to use the Explicit way instead of Interactive one.
Output from Interactive Mode

$ ./move-wsl
1) Ubuntu-20.04(Default)
Select distro to move: 1
Enter WSL target directory: E:\WSL

Move WSL 'Ubuntu-20.04(Default)' to E:WSL? (Y|n) Y
Creating target dir "E:WSL" ...
Exporting VHDX to "E:WSL/Ubuntu-20.04(Default).tar" ...
There is no distribution with the supplied name.
ERROR: Export failed. E:WSL/Ubuntu-20.04(Default).tar does not exist.

Output from wsl -l command

PS Z:\> wsl -l
Windows Subsystem for Linux Distributions:
Ubuntu-20.04 (Default)

Batch util doesn't consider resized vdisk

Describe the bug
A clear and concise description of what the bug is.
Batch util results in default vdisk size when importing. (not tested: bash/PowerShell versions)
Please add terminal output if possible:
I had resized my vdisk using the guide here. However after running the batch utility my vdisk had resized to its default of 256M.

Script version:

  • Bash
  • Powershell
  • Batch

Pre-check: destination is not at root of drive

Describe the bug
Seems like wsl --import will fail with "access is denied" if attempting to import at the root of a disk.

Please add terminal output if possible:

jdsmi@YAMI ❯ ~\dev\scripts ❯
❯ .\Move-WSL.ps1
Getting distros...
Select distro to move:
1: Arch
2: docker-desktop
3: docker-desktop-data
1
Enter WSL target directory:
F:\
Move Arch to "F:"? (Y|n): Y
Exporting VHDX to "F:\Arch.tar" ...
Unregistering WSL ...
Importing Arch from F:...
Access is denied.
Write-Error: Import failed. Distro not found. Export file at F:\Arch.tar
⨯ jdsmi@YAMI ❯ ~\dev\scripts ❯
❯ wsl --import Arch F:\ F:\Arch.tar
Access is denied.

Moved Arch.tar to F:\arch\Arch.tar

jdsmi@YAMI ❯ ~\dev\scripts ❯
❯ wsl --import Arch F:\arch F:\arch\Arch.tar
jdsmi@YAMI ❯ ~\dev\scripts ❯
❯

Script version:

  • Bash
  • Powershell
  • Batch

Pre-check: destination is not compressed

Describe the bug
If the destination import directory is marked as "compressed", the import stage will fail due to .vhdx files not being compressable.

Please add terminal output if possible:

jdsmi@YAMI ❯ ~\dev\scripts ❯
❯ .\Move-WSL.ps1
Getting distros...
Select distro to move:
1: docker-desktop
2: Arch
3: docker-desktop-data
1
Enter WSL target directory:
F:\docker\
Move docker-desktop to "F:\docker"? (Y|n): Y
Exporting VHDX to "F:\docker\docker-desktop.tar" ...
Unregistering WSL ...
Importing docker-desktop from F:\docker...
The requested operation could not be completed due to a virtual disk system limitation.  Virtual hard disk files must be uncompressed and unencrypted and must not be sparse.
Write-Error: Import failed. Distro not found. Export file at F:\docker\docker-desktop.tar

Disabled compression on the destination folder.

⨯ jdsmi@YAMI ❯ ~\dev\scripts ❯
❯ wsl --import docker-desktop F:\docker F:\docker\docker-desktop.tar
jdsmi@YAMI ❯ ~\dev\scripts ❯
❯

Script version:

  • Bash
  • Powershell
  • Batch

Fails with `ERROR: Import failed. Target file not found.` if using WSL1

I tried moving my newly created distribution, and it failed with the message :

ERROR: Import failed. Target file not found.

Indeed, I forgot to set the default version, and the distribution was using WSL1.

The script expected a file named "ext4.vhdx", while I had a rootfs folder.

Please either check for the existence of either ext4.vhdx or the rootfs folder, or explain in the message that it might be caused by the distribution being WSL1.

Docker Desktop WSL will crash after moving to another Drive

Docker Desktop WSL will crash after moving to another Drive
After I moved docker-desktop and docker-desktop-data to another drive I got errors.

  • First, it would crash the current docker and ask for a restart.
  • When I restarted I got this error:

image

What I did:

  • Moved docker-desktop-data
  • Moved docker-desktop
  • Then it got an error, and I restarted docker desktop, then the error window popped out

Script version:

  • Bash
  • Powershell
  • Batch

PLEASE CHECK INPUT BEFORE TAKING ACTION [DANGER ZONE]!!!!

dude please check inputs before unregistering WSL! the script unregistered and cleared everything and after that send an error that the target location is incorrect!!!!!!
it deleted my virtual machine along with my codes, installs files etc.!! and now I have no way of turning back :((((( I have to reinstall even the whole WSL! since even wsl is not functioning well :(
the script is really dangerous!

image

About the method for changing default user in FAQ

The method presented in readme for changing default user was not possible for me
I was unable to locate "etc/wsl.conf" in either my PC or my Linux distro.

After a search, I found this and this as a working solution.

For example in my PC the command was like this:
ubuntu1804.exe config --default-user kamran

Please update the FAQ in the readme to this solution as it is working and standard.

After moving wsl does not create ext4.vhdx

PS K:\docker> ./move-wsl.ps1
Getting distros...
Select distro to move:
1: Ubuntu-18.04
2: docker-desktop-data
3: docker-desktop
2
Enter WSL target directory:
./docker-desktop-data
Move docker-desktop-data to "./docker-desktop-data"? (Y|n): Y
Exporting VHDX to ".\docker-desktop-data\docker-desktop-data.tar" ...
Unregistering WSL ...
Importing docker-desktop-data from ./docker-desktop-data...
Cleaning up ...
Done!
PS K:\docker>

Expect in folder ext4.vhdx
but has two folders rootfs and temp

Error - Insufficient system resources exist to complete the requested service.

Describe the bug
i am just trying to move the ubuntu 20 wsl from my OS drive to a external hard disk , i am getting the error mentioned in question . i am using powershell to do this process . The whole error message is as follows :

PS D:\apps\setup\move-wsl-master> ./move-wsl.ps1
Getting distros...
Select distro to move:
1: Ubuntu-20.04
1
Enter WSL target directory:
D:\apps\Ubuntu_20
Move Ubuntu-20.04 to "D:\apps\Ubuntu_20"? (Y|n): y
Exporting VHDX to "D:\apps\Ubuntu_20\Ubuntu-20.04.tar" ...
Insufficient system resources exist to complete the requested service.
D:\apps\setup\move-wsl-master\move-wsl.ps1 : ERROR: Export failed
At line:1 char:1
+ ./move-wsl.ps1
+ ~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,move-wsl.ps1

Cleaning up ...
PS D:\apps\setup\move-wsl-master>

Script version:

  • Powershell - 5.1.19041.1

switch to "wsl -l -q" to get distro names

This is great and it helped me a lot since I am hitting issues with my system drive.
Thank you for the great work!
I would suggest we switch from wsl -l to wsl -l -q to get distro names more safely instead of having to deal with manual string parsing.

BTW I created a PowerShell version. LMK if you are interested and I can send a PR.

Dealing with the wsl output encoding in PowerShell was a bit fun...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.