Moving WSL2's VHDX file to a different location

I, like anyone who's been using Windows Subsystem for Linux, was excited when WSL2 was finally released.  I was even more excited when Docker released support for WSL2.  But, that excitement quickly went away once I started building containers.

With WSL2, images/containers are now stored in the virtual machine's VHDX image.  When images/containers are purged, space is freed inside the VHDX, but is never released back to the host OS.  This can cause the VHDX file to start balooning out of control, which is problematic if your primary boot drive is low on space.  This is a known issue, and this GitHub issue has a workaround for shrinking the image (some of those steps are listed below).

To work around this, you can move the VHDX to a different drive/partition.  Here's a PowerShell script do do it (USE AT YOUR OWN RISK):

$ErrorActionPreference = "Stop"

$newLocation = "E:\VMs\WSL2\"

cd ~\AppData\Local\Docker\wsl\data
wsl --shutdown
Optimize-VHD .\ext4.vhdx -Mode Full
mkdir $newLocation -Force
mv ext4.vhdx $newLocation
cd ..
rm data
New-Item -ItemType SymbolicLink -Path "data" -Target $newLocation

Just change the $newLocation parameter, and it'll move the VHDX file to the new location.  If you're using Windows 10 Home, you can use this workaround for the Optimize-VHD command.  This will stop WSL, optimize the VHD (which releases unallocated space inside the VHDX back to the host OS), moves the VHDX to the new location, and replaces the "data" folder with a symlink to the new location.

I've done limited testing, and everything seems to work as expected.  If you run into issues, let me know in the comments!

Note: If you're running Docker for Windows without WSL/WSL2, these steps may work with DockerDesktop.vhdx...but in that case, you may want to just change the VHDX location in the Hyper-V VM instance.