♫ Garbage - Only Happy When It Rains (1995) ♪
.
Declutter your WSL - the easy way. (Photograph by Gerald Herbert/AP)
This PowerShell script automates the process of compacting WSL2 ext4.vhdx files, which can help free up a lot of disk space on your Windows system.
Note
The initial release is the subject of a tutorial designed as a practical introduction to PowerShell. It is available on fCC News.
Contents - click to expand
Windows Subsystem for Linux (WSL 2) uses a virtualization platform to install Linux distributions alongside the host Windows operating system. For that, it creates a Virtual Hard Disk (VHD) to store files for each of the Linux distributions that you install. These VHDs use the ext4 file system type and are represented on your Windows hard drive as an ext4.vhdx file.
WSL 2 automatically resizes these VHD files to meet storage needs. This means that the VHD file starts small and grows as needed. Initially, it may only take up a few gigabytes, but as you install applications and create files within your Linux environment, the VHD expands to accommodate the additional data.
Note
When you delete files or uninstall applications, the VHD does not automatically shrink.
This is a bit problematic, especially when you deal with a lot of data and dependencies in your workflow (data science..). Furthermore, the process of regaining the lost space is a bit cumbersome.
Tip
It's probably a matter of time before the issue is solved. Microsoft rolled out some new experimental features dealing with that, but careful, some users testing it have complained about data loss. More about this on superuser.
Until then you are free to use this script :)
- Storage efficiency: helps recover unused space in WSL2 distributions without hassle.
- Fast and universal: prefers
Optimize‑VHDon Hyper‑V systems (faster, more robust), with adiskpartfallback for broader compatibility. - Automation-friendly: no need to manually locate and compact the
ext4.vhdx file! Possibility to pass the distro name as an argument. - User-friendly: simple interface with basic reporting.

PowerShell screenshot : first distro selected in interactive mode (diskpart fallback).
- Administrator privileges: the script needs to be run with administrative rights.
- PowerShell: make sure you have PowerShell installed on your system (by default on Windows 10/11).
- WSL2: this script is designed only for WSL2 distributions.
To run the script, follow these steps:
- Download or clone this repository.
- Open Command Prompt or PowerShell as an administrator.
- Navigate to the directory containing the
wsl_compactor.ps1file. - Execute the script with the following command:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\wsl_compactor.ps1Non-interactive mode:
Tip
You can list the distros available from your system with:
wsl.exe --listWhen -DistroName or -All are supplied, the script runs without confirmation prompt. Example with an Ubuntu distro:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\wsl_compactor.ps1 -DistroName UbuntuEasy! Just click (you will be prompted for an Admin elevation). See the section below and the release section.
The script is also available in the PowerShell gallery. This can simplify automation tasks. It is advised to use at least PowerShell 5.1 In an elevated PowerShell terminal (run as Administrator).
Make sure PowerShellGet and and PackageManagement are available on the system:
Install-Module -Name PowerShellGet -Force -AllowClobber
Install-Module -Name PackageManagement -Force -AllowClobberNote
You might also be prompted to install NuGet.
Installation:
Install-Script -Name wsl2compactTip
You can install system-wide by appending the following argument -Scope AllUsers (by default the scope is CurrentUser) to the installation comand.
If you get an ExecutionPolicy warning, you can precede the installation command and run PowerShell with powershell.exe -NoProfile -ExecutionPolicy Bypass or set a temporary policy Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force
Run the script:
Note
Get-Command wsl2compact helps you locate the script on your system.
powershell.exe -NoProfile -ExecutionPolicy Bypass -File $((Get-Command wsl2compact).Source)or optionally, specify a -DistroName or -All to run in non-interactive mode:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File $((Get-Command wsl2compact).Source)
-DistroName UbuntuWSL-VHDX-Compact is now also a Windows executable! Check the release section.
Every release includes a checksums.txt and is cryptographically attested by GitHub Actions, so you can confirm a binary actually came from this repo's build pipeline, unmodified.
Check the SHA256 checksum:
Open a terminal from the location of the .exe and compare the content of checksums.txt with the output of this command:
Get-FileHash .\wsl2compact.exe -Algorithm SHA256Verify build provenance (requires the GitHub CLI):
gh attestation verify .\wsl2compact.exe -R hyperphantasia/WSL-VHDX-CompactThis command verifies and confirms that your wsl2compact.exe was built by this GitHub Actions workflow from the exact commit tagged in the release and not modified or built anywhere else.
This project is not yet code-signed. I've applied for a free certificate. This section will be updated once signing is in place.
Note
wsl2compact.exe is built with PS2EXE from the .ps1 script in this repo. Nothing more.
A small number of antivirus engines occasionally flag freshly-built, unsigned Windows executables as suspicious based on heuristics rather than actual content. This is a well-documented false-positive pattern for small open-source tools that is not unique to this project.
Since you will be prompted to run a powershell script with elevated rights, be rigorous: read below how to check the contents of the .exe by yourself. If you'd rather avoid it entirely, use the PowerShell Gallery install method above, or read and run wsl_compactor.ps1 directly: it's plain, unobfuscated PowerShell.
After installing PS2Exe like this:
Install-Module -Name ps2exe -Scope CurrentUserYou can unpack the .exe :
Import-Module ps2exe
Invoke-PS2EXE -extract .\wsl2compact.exe -OutPath .\extractedAnd then inspect its content :)
The only difference with wsl_compactor.ps1 script should be the two lines bottom lines appended during packaging stage by the release.yml file (this maintains the terminal screen active and exit only on user input).
Write-Host "`nPress any key to exit..." -ForegroundColor DarkCyan
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")The script performs the following actions:
- Verifies Administrator privileges.
- Enumerates installed WSL2 distributions (from the registry).
- Selects a distribution (via
-DistroName, interactive menu if multiple, or all distros via-All, or the single installed distro). - Identifies the base path and locates the
ext4.vhdxfile. - Runs
fstriminside the distro to discard unused blocks. - Shuts down WSL.
- Attempts to compact using Hyper‑V
Optimize-VHD -Mode Full; if Hyper‑V is unavailable orOptimize‑VHDfails, falls back to thediskpartmethod. - Reports previous size, current size, and saved disk space.
- The script throws errors on missing admin rights, missing registry entries, missing ext4.vhdx file, or failed WSL shutdown.
- When
fstrimfails it logs a warning and continues.
- If multiple distributions are installed, you'll be prompted to select one.
- In interactive mode (no
-DistroName/-Allargument passed) The script will confirm the selected distribution before proceeding with compaction. Optimize‑VHDis preferred on machines with Hyper‑V (Windows Pro/Enterprise).diskpartworks on broader editions but may be slower.- Be patient. If there is a lot of compacting ahead, the script might take a while to execute.
Warning
As always when dealing with important data: make sure to have backups!
This script is compatible with Windows systems that have WSL2 installed. It has been tested on Windows 10 and Windows 11.
- Added: implemented CI/CD pipeline powered by github actions. Each push on the main branch:
- Pushes the
.ps1script on PowerShell Gallery - Packages a Windows executable with PS2EXE and pushes the
.exeas a new github release.
- Pushes the
- Added: implemented a one choice option (
-All) to compact all available distros sequentially.
- Bugfixes: fixed distro enumeration listing and early exit error. PR#4 by @AlexanderDoerr
- Added: prefer
Optimize-VHD(Hyper‑V module) with automatic fallback to diskpart if Hyper‑V is unavailable or Optimize‑VHD fails issue#2. - Added:
-DistroNameparameter for easier automation. - Added:
fstriminside the distro prior to compaction to discard unused blocks issue#2. - Added: more explicit admin check (throws early if not elevated).
- Added: reporting of previous/current sizes and bytes saved. PR#1 by @lrotova.
- Released: WSL2Compact v1.0.0 Windows executable.
- Initial release.
Contributions are welcome! If you have any improvements or bug fixes, feel free to submit them via GitHub.
Do what you want with the code, this script is released under the Unlicense license.