Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      Coded Smorgasbord: High Strung

      September 26, 2025

      Chainguard launches trusted collection of verified JavaScript libraries

      September 26, 2025

      CData launches Connect AI to provide agents access to enterprise data sources

      September 26, 2025

      PostgreSQL 18 adds asynchronous I/O to improve performance

      September 26, 2025

      Distribution Release: Neptune 9.0

      September 25, 2025

      Distribution Release: Kali Linux 2025.3

      September 23, 2025

      Distribution Release: SysLinuxOS 13

      September 23, 2025

      Development Release: MX Linux 25 Beta 1

      September 22, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      PHP 8.5.0 RC 1 available for testing

      September 26, 2025
      Recent

      PHP 8.5.0 RC 1 available for testing

      September 26, 2025

      Terraform Code Generator Using Ollama and CodeGemma

      September 26, 2025

      Beyond Denial: How AI Concierge Services Can Transform Healthcare from Reactive to Proactive

      September 25, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured

      Distribution Release: Neptune 9.0

      September 25, 2025
      Recent

      Distribution Release: Neptune 9.0

      September 25, 2025

      FOSS Weekly #25.39: Kill Switch Phones, LMDE 7, Zorin OS 18 Beta, Polybar, Apt History and More Linux Stuff

      September 25, 2025

      Distribution Release: Kali Linux 2025.3

      September 23, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»Development»How to Free Up and Automatically Manage Disk Space for WSL on Windows 10/11

    How to Free Up and Automatically Manage Disk Space for WSL on Windows 10/11

    August 7, 2025

    Windows Subsystem for Linux (WSL) lets you run a Linux environment directly on Windows. This is particularly useful for web development where you can develop and test applications in a Linux environment without leaving Windows. You can even run freeCodeCamp locally with it!

    But managing disk space can be a quite a challenge, as WSL uses virtual hard disks that do not automatically free up unused space.

    This tutorial will guide you through the process of manually compacting your WSL virtual hard disks. We’ll automate this task using a PowerShell script, ensuring that your WSL environment remains efficient and clutter-free.

    Reclaim Your Space

    WSL uses a virtualization platform to install Linux distributions on your Windows system. Each distribution you add gets its own Virtual Hard Disk (VHD), which uses the ext4 file system (common in Linux). It’s saved on your Windows drive as an ext4.vhdx file.

    Key issues here:

    • Inefficient storage: by default, VHD files do not reclaim unused space. This means that when you delete a file in WSL, the associated disk space isn’t immediately freed up.

    • Disk space consumption: due to that inefficient storage, the VHD files can grow large thanks to that accumulated data, especially if you’re a WSL heavy user.

    • Need for maintenance: you may not know that you need to compact your VHD files in order to reclaim disk space.

    If you notice that your free disk space is shrinking even after deleting files and apps, WSL might be the reason. This tutorial will help you keep your WSL and Windows environment running smoothly.

    Table of Contents

    • Part 1: How to Manually Compact Your Virtual Hard Disk

      • Prerequisites

      • Step 1: Verify your WSL version and status

      • Step 2: List all installed distributions verbosely

      • Step 3: Locate your linux Virtual Hard Drive (VHDX) path

      • Step 4: Shut down all WSL instances

      • Step 5: Compact the Linux virtual hard drive using DiskPart

      • Step 6: Restart WSL and verify

    • Part 2: How to Make Your Life Easier with Automation

      • Prerequisites

      • Step 1: Find out installed WSL2 distributions

      • Step 2: Select a distro to compact

      • Step 3: Locate the ext4.vhdx File

      • Step 4: The confirmation prompt

      • Step 5: Shut Down WSL and compact

      • Step 6: Run a DiskPart script

    Part 1: How to Manually Compact Your Virtual Hard Disk

    Let’s start by going through the process manually. This section will guide you through checking your WSL version and associated Linux distributions, finding VHD files, shutting down WSL, and compacting the virtual disk.

    Prerequisites

    • Windows 10 (20H1/2004+) or Windows 11 with WSL2 installed

    • The PowerShell or Command Prompt running as Administrator (from the Windows menu, right click the icon and choose run as Administrator).

    Step 1: Verify your WSL version and status

    First, make sure you’re running on WSL version 2 (commonly referred as WSL2). The first version is outdated and WSL2 provides significant improvements. Open PowerShell (as Admin) or Command Prompt (as Admin) and run:

    wsl <span class="hljs-literal">-v</span>
    
    wsl -<span class="hljs-literal">-status</span>
    

    These commands display the WSL client version and whether your default distro is using WSL 2. Here’s the output of the wsl -v command:

    Command prompt displaying WSL version 2.5.9.0, with corrupted or incomplete text following "Kernel version:", "WSLg version:", and other version labels.

    And here’s the output of the wsl --status command.

    Command line text showing "C:Users>wsl --status" with the information "Default Distribution: Ubuntu" and "Default Version: 2".

    Step 2: List all installed distributions verbosely

    To see a detailed list of your WSL distributions (including which version each uses), run:

    wsl.exe -<span class="hljs-literal">-list</span> -<span class="hljs-literal">-verbose</span>
    

    Output of  the WSL --list --verbose command.

    Above you can see the output of the WSL --list --verbose command.

    Look for your distro name (for example, “Ubuntu”) and note its WSL version. If it shows “Version 2”, you can proceed with compaction.

    Step 3: Locate your linux Virtual Hard Drive (VHDX) path

    Each WSL distro’s files live in a VHDX file on your Windows drive. To find the path for any Linux distribution, use this PowerShell snippet:

    (<span class="hljs-built_in">Get-ChildItem</span> `
    
    <span class="hljs-literal">-Path</span> HKCU:SoftwareMicrosoftWindowsCurrentVersionLxss `
    
    | <span class="hljs-built_in">Where-Object</span> { <span class="hljs-variable">$_</span>.GetValue(<span class="hljs-string">"DistributionName"</span>) <span class="hljs-operator">-eq</span> <span class="hljs-string">'YOUR_DISTRO_NAME'</span> }
    
    ).GetValue(<span class="hljs-string">"BasePath"</span>) + <span class="hljs-string">"ext4.vhdx"</span>
    

    Where you replace YOUR_DISTRO_NAME with yours (Ubuntu, Debian, Kali-linux..). Here’s the output of the command shown above in PowerShell (the filepath has been anonymized):

    A PowerShell command is displayed, used to locate the ext4.vhdx file for the Ubuntu distribution. The command retrieves the Windows Subsystem for Linux (WSL) base path for Ubuntu.

    This command reads the registry key for your linux distribution, then appends “ext4.vhdx” to build the full file path.

    Make sure you copy the whole line. We will need it in later stages.

    Step 4: Shut down all WSL instances

    Before you can compact any virtual drive, make sure WSL is completely shut down. In PowerShell or Command Prompt (still as Administrator), run:

    wsl.exe -<span class="hljs-literal">-shutdown</span>
    

    Step 5: Compact the Linux virtual hard drive using DiskPart

    You successfully gathered all the needed information (about your system, the available distros, and their VHDX filepath) to proceed with the main task. In this step, you actually proceed with the compaction.

    1. Launch DiskPart in the same elevated (admin) shell:
    diskpart
    

    DiskPart will open in a new window. It’s a Windows command-line tool for managing disk partitions. Be cautious when using it, as incorrect actions can cause serious data loss.

    1. In the DiskPart prompt, select the VHDX file you found earlier. Replace the path as displayed below with your actual path (the line you copied before):
    <span class="hljs-built_in">select</span> vdisk file=<span class="hljs-string">"C:UsersusernameAppDatapathtoext4.vhdx"</span>
    

    Screenshot of a command prompt window showing Microsoft DiskPart version information. A command is entered to select a virtual disk file, and a message confirms successful selection.

    The above is the output of the select vdisk command (some data has been anonymized).

    1. Attach the virtual drive in read-only mode:

    Compaction only needs to scan the empty blocks in the file, not write to the Linux filesystem inside. Read-only mode guarantees that DiskPart only inspect the blocks for zero‐trimming without any chance of damaging or altering your Linux filesystem.

    attach vdisk readonly
    

    Command prompt showing the output for "DISKPART> attach vdisk readonly" with a successful attachment message.

    You can see in the screenshot above that the virtual hard drive has been successfully attached.

    1. Compact the disk:

    This frees up the disk space by shrinking the physical size of the .vhdx file to match the actual used data inside.

    compact vdisk
    

    This operation might take a while. When you see the “DiskPart successfully compacted the virtual disk file” message, proceed with the next step. In the image below, the virtual hard drive has been successfully compacted.

    Terminal output showing "DISKPART> compact vdisk" with "100 percent completed," indicating successful compaction of the virtual disk file.

    1. Detach the virtual drive:
    detach vdisk
    

    Command prompt showing "DISKPART> detach vdisk" and a confirmation message that DiskPart successfully detached the virtual disk file.

    There you go – the virtual hard drive has been successfully detached.

    This command releases any locks on the virtual drive and effectively dismounts it. If you don’t use this command, the file remains “in use,” preventing WSL (or you) from accessing it until you reboot or manually force it closed.

    6. Exit DiskPart:

    <span class="hljs-keyword">exit</span>
    

    Step 6: Restart WSL and verify

    Back in PowerShell or Command Prompt, you can relaunch your distro:

    wsl <span class="hljs-literal">-d</span> YOUR_DISTRO_NAME
    

    You can even try the Unix df -h command in your WSL prompt to check your new available disk spaces.

    Congrats, you just achieved a maintenance task that can free up lots of gigabytes of storage over time. Now, it’s time to automate.

    A minimalistic white rectangular button with a cable on a pink surface.

    Part 2: How to Make Your Life Easier with Automation

    Since it’s often hard to remember exactly where your WSL distro is located and you probably won’t use it very often, this PowerShell script will automate the entire process we covered in part 1. Here’s a preview of the steps you’ll follow:

    • Detect installed WSL distributions.

    • Select one (and handle the cases there are more than one).

    • Locate the corresponding ext4.vhdx file.

    • Shut down WSL and use DiskPart to compact the virtual disk.

    Prerequisites

    • Windows 10 (20H1/2004+) or Windows 11 with WSL 2 enabled.

    • PowerShell or Command Prompt (as Administrator).

    You’ll also need a code editor. The Windows notepad is enough for completing this task. You can also use an IDE (Integrated Development Environment) like VS Code or an ISE (Integrated Scripting Environment) like PowerShell ISE (included with Windows).

    To test the script, download it from GitHub. Open an elevated PowerShell or Command Prompt and navigate to the script’s folder. With just the command below, you will be able to run it and free up some disk space:

    powershell.exe <span class="hljs-literal">-NoProfile</span> <span class="hljs-literal">-ExecutionPolicy</span> Bypass <span class="hljs-operator">-File</span> .wsl_compactor.ps1
    

    Step 1: Find out installed WSL2 distributions

    One of the main challenges is to find the Linux distributions available on the host system. Let’s check the first block and see what’s it about:

    <span class="hljs-variable">$lxssKey</span> = <span class="hljs-string">'HKCU:SoftwareMicrosoftWindowsCurrentVersionLxss'</span>
    <span class="hljs-variable">$distros</span> = <span class="hljs-built_in">Get-ChildItem</span> <span class="hljs-variable">$lxssKey</span> | <span class="hljs-built_in">ForEach-Object</span> {
        <span class="hljs-variable">$p</span> = <span class="hljs-built_in">Get-ItemProperty</span> <span class="hljs-variable">$_</span>.PSPath
        [<span class="hljs-type">PSCustomObject</span>]<span class="hljs-selector-tag">@</span>{
            Name     = <span class="hljs-variable">$p</span>.DistributionName
            BasePath = <span class="hljs-variable">$p</span>.BasePath
        }
    }
    

    WSL records each distribution under this windows registry key:

    HKCU:SoftwareMicrosoftWindowsCurrentVersionLxss

    Each subkey has two important values:

    • DistributionName (for example, Ubuntu)

    • BasePath (This is where the distribution files are stored. It’s the directory that contains the ext4.vhdx file.)

    The script uses Get-ChildItem and Get-ItemProperty to enumerate these subkeys and build a list of available Linux distributions.

    <span class="hljs-keyword">if</span> (<span class="hljs-variable">$distros</span>.Count <span class="hljs-operator">-eq</span> <span class="hljs-number">0</span>) {
    <span class="hljs-keyword">Throw</span><span class="hljs-operator">-And</span><span class="hljs-literal">-Exit</span> <span class="hljs-string">"No WSL distros found in the registry."</span>
    }
    

    If no distributions are found, the script terminates and prints this error message on the terminal: "No WSL distros found in the registry.”

    Step 2: Select a distro to compact

    Here, the process has two steps:

    • If multiple distros are found, it displays all the distros with a numbered menu and prompts you to choose one:
    <span class="hljs-keyword">if</span> (<span class="hljs-variable">$distros</span>.Count <span class="hljs-operator">-gt</span> <span class="hljs-number">1</span>) {
        <span class="hljs-built_in">Write-Host</span> <span class="hljs-string">"Multiple distros detected. Please choose one:`n"</span>
    
        <span class="hljs-keyword">for</span> (<span class="hljs-variable">$i</span> = <span class="hljs-number">0</span>; <span class="hljs-variable">$i</span> <span class="hljs-operator">-lt</span> <span class="hljs-variable">$distros</span>.Count; <span class="hljs-variable">$i</span>++) {
            <span class="hljs-built_in">Write-Host</span> <span class="hljs-string">"[<span class="hljs-variable">$</span>(<span class="hljs-variable">$i</span>+1)] <span class="hljs-variable">$</span>(<span class="hljs-variable">$distros</span>[<span class="hljs-variable">$i</span>].Name)"</span>
        }
        <span class="hljs-variable">$selected</span> = <span class="hljs-variable">$distros</span>[[<span class="hljs-built_in">int</span>]<span class="hljs-variable">$choice</span> - <span class="hljs-number">1</span>]
    }
    

    The computed menu will look like this:

    Multiple distros detected. Please choose one:
    
    [1] Ubuntu 20.04
    
    [2] Debian
    
    [3] Alpine
    
    • If only one distribution is found on the host system, the script selects it automatically:
    <span class="hljs-keyword">else</span> {
    <span class="hljs-variable">$selected</span> = <span class="hljs-variable">$distros</span>[<span class="hljs-number">0</span>]
    }
    

    When setting up a distribution, whether chosen manually by the user or selected automatically, the important information is the path to each distribution’s virtual hard disk. This path is saved in two main variables: 'distro' (which identifies the specific distribution) and 'basePath' (which shows where its virtual disk is located).

    <span class="hljs-variable">$distro</span> = <span class="hljs-variable">$selected</span>.Name
    <span class="hljs-variable">$basePath</span> = <span class="hljs-variable">$selected</span>.BasePath
    
    <span class="hljs-built_in">Write-Host</span> <span class="hljs-string">"`nSelected distro: <span class="hljs-variable">$distro</span>"</span> <span class="hljs-literal">-ForegroundColor</span> DarkYellow
    <span class="hljs-built_in">Write-Host</span> <span class="hljs-string">"BasePath: <span class="hljs-variable">$basePath</span>"</span>
    

    The lines above display an output that looks like this:

    Selected distro: Ubuntu (or any other distro)
    BasePath: C:Users<span class="xml"><span class="hljs-tag"><<span class="hljs-name">User_name</span>></span></span>AppDataLocalPackages…
    

    Like for all other steps, it’s important to consider the case of something going wrong, by throwing an error and exiting the program:

    <span class="hljs-keyword">if</span> (<span class="hljs-operator">-not</span> (<span class="hljs-built_in">Test-Path</span> <span class="hljs-variable">$basePath</span>)) {
    <span class="hljs-keyword">Throw</span><span class="hljs-operator">-And</span><span class="hljs-literal">-Exit</span> <span class="hljs-string">"BasePath '<span class="hljs-variable">$basePath</span>' does not exist on disk."</span>
    }
    

    Step 3: Locate the ext4.vhdx File

    In the first step, we collected the information we need about the available distributions and where they are stored on the Windows system. By choosing an entry (either manually or automatically), we can find the correct file. Sometimes, the ext4 file is located between the base path and a LocalState folder. This script manages both situations. It builds the usual locations where the file can be found.

    They look like this:

    • $BasePathext4.vhdx

    • $BasePathLocalStateext4.vhdx

    This can translate into something like this on your system (option 1):

    C:UsersAliceAppDataLocalPackagesCanonicalGroupLimited.Ubuntu20.04onWindows<span class="hljs-emphasis">_79rhkp1fndgscext4.vhdx</span>
    

    or like this (option 2):

    C:UsersAliceAppDataLocalPackagesCanonicalGroupLimited.Ubuntu20.04onWindows<span class="hljs-emphasis">_79rhkp1fndgscLocalStateext4.vhdx</span>
    

    (You might find out that your WSL2 distro is located in some other directory than “Packages” – but don’t worry, your BasePath will match the correct folders).

    The idea is to build the two possible path options:

    <span class="hljs-variable">$possible</span> = <span class="hljs-selector-tag">@</span>(
    <span class="hljs-built_in">Join-Path</span> <span class="hljs-variable">$basePath</span> <span class="hljs-string">'ext4.vhdx'</span>
    <span class="hljs-built_in">Join-Path</span> <span class="hljs-variable">$basePath</span> <span class="hljs-string">'LocalStateext4.vhdx'</span>
    )
    

    And pick the first one that actually contains the file:

    <span class="hljs-variable">$vhdx</span> = <span class="hljs-variable">$possible</span> | <span class="hljs-built_in">Where-Object</span> { <span class="hljs-built_in">Test-Path</span> <span class="hljs-variable">$_</span> } | <span class="hljs-built_in">Select-Object</span> <span class="hljs-literal">-First</span> <span class="hljs-number">1</span>
    

    Again, we throw an error message if no suitable file is found:

    <span class="hljs-keyword">if</span> (<span class="hljs-operator">-not</span> <span class="hljs-variable">$vhdx</span>) {
    <span class="hljs-keyword">Throw</span><span class="hljs-operator">-And</span><span class="hljs-literal">-Exit</span> <span class="hljs-string">"No ext4.vhdx found under '<span class="hljs-variable">$basePath</span>'."</span>
    }
    

    Step 4: The confirmation prompt

    Disk management tools require caution and you need to understand the potential consequences of your actions. A confirmation prompt is always a good safeguard to prevent accidental data loss or unwanted system changes.

    Before proceeding, the script shows you:

    • a Distro name

    • its BasePath

    • the VHDX file path

    <span class="hljs-built_in">Write-Host</span> <span class="hljs-string">"`nAbout to compact this WSL distro:"</span> <span class="hljs-literal">-ForegroundColor</span> Magenta
    <span class="hljs-built_in">Write-Host</span> <span class="hljs-string">" Distro : <span class="hljs-variable">$distro</span>"</span>
    <span class="hljs-built_in">Write-Host</span> <span class="hljs-string">" BasePath : <span class="hljs-variable">$basePath</span>"</span>
    <span class="hljs-built_in">Write-Host</span> <span class="hljs-string">" VHDX file: <span class="hljs-variable">$vhdx</span>`n"</span>
    

    It then prompts “Are you sure you want to proceed? (Y/N)”:

    <span class="hljs-built_in">Write-Host</span> <span class="hljs-string">"Are you sure you want to proceed? (Y/N) "</span> <span class="hljs-literal">-ForegroundColor</span> DarkCyan <span class="hljs-literal">-NoNewline</span>
    
    <span class="hljs-comment"># Then read the response</span>
    <span class="hljs-variable">$answer</span> = <span class="hljs-built_in">Read-Host</span>
    

    You’re then prompted to Type Y (case-insensitive) to continue or anything else to cancel.

    <span class="hljs-keyword">if</span> (<span class="hljs-variable">$answer</span>.ToUpper() <span class="hljs-operator">-ne</span> <span class="hljs-string">'Y'</span>) {
        <span class="hljs-built_in">Write-Warning</span> <span class="hljs-string">"Operation canceled"</span>
        <span class="hljs-keyword">exit</span>
    }
    

    For the two steps above, I had to use a trick to print the question in color but a simple option (without colors) could be:

    <span class="hljs-keyword">if</span> ((<span class="hljs-built_in">Read-Host</span> <span class="hljs-string">'Are you sure you want to proceed? (Y/N)'</span>).ToUpper() <span class="hljs-operator">-ne</span> <span class="hljs-string">'Y'</span>) { 
        <span class="hljs-built_in">Write-Warning</span> <span class="hljs-string">'Operation canceled'</span>
        <span class="hljs-keyword">exit</span> 
    }
    

    Step 5: Shut down WSL and compact

    Before proceeding to the DiskPart utility, it’s important to stop all running WSL instances. Pass the shutdown command directly in PowerShell.

    <span class="hljs-built_in">Write-Host</span> <span class="hljs-string">"Shutting down WSL…"</span> <span class="hljs-literal">-ForegroundColor</span> Cyan
    wsl.exe –shutdown
    

    A common mistake is to forget to launch PowerShell or the Command Prompt with Administrator rights. You can prevent this case with a message:

    <span class="hljs-keyword">if</span> (<span class="hljs-variable">$LASTEXITCODE</span> <span class="hljs-operator">-ne</span> <span class="hljs-number">0</span>) {
         <span class="hljs-keyword">Throw</span><span class="hljs-operator">-And</span><span class="hljs-literal">-Exit</span> <span class="hljs-string">"Failed to shut down WSL (exit code <span class="hljs-variable">$LASTEXITCODE</span>). Are you running as Administrator?"</span>
    }
    

    Step 6: Run a DiskPart script

    Building the script:

    The process is the same as in the manual part, but this time, we ‘inject’ the ready-to-go DiskPart commands into the script.

    <span class="hljs-variable">$dpScript</span> = <span class="hljs-string">@"
    select vdisk file="<span class="hljs-variable">$vhdx</span>"
    attach vdisk readonly
    compact vdisk
    detach vdisk
    exit
    "@</span>
    

    Before launching, there are two steps you need to take:

    1. The PowerShell script writes the lines above to a temporary file:
    <span class="hljs-variable">$tempFile</span> = [<span class="hljs-type">IO.Path</span>]::GetTempFileName()
    <span class="hljs-built_in">Set-Content</span> <span class="hljs-literal">-LiteralPath</span> <span class="hljs-variable">$tempFile</span> <span class="hljs-literal">-Value</span> <span class="hljs-variable">$dpScript</span> <span class="hljs-literal">-Encoding</span> ASCII
    

    This is the equivalent to the commands passed in the manual part:

    select vdisk file="C:…ext4.vhdx" # full path to the vdisk file

    attach vdisk readonly

    compact vdisk

    detach vdisk

    exit

    1. Compacting can take a while, especially if you’ve never de-cluttered your virtual drive before. It’s wise to show a warning before proceeding:
    <span class="hljs-built_in">Write-Host</span> <span class="hljs-string">"Running DiskPart to compact the VHDX. Be patient, this might take a while..."</span> <span class="hljs-literal">-ForegroundColor</span> Cyan
    

    Invoke DiskPart:

    <span class="hljs-comment"># Run DiskPart with the script saved to the temporary file and process each output line as it arrives</span>
    diskpart /s <span class="hljs-variable">$tempFile</span> | <span class="hljs-built_in">ForEach-Object</span> {
        <span class="hljs-comment"># Grab any "NN percent" type message from the line</span>
        <span class="hljs-keyword">if</span> (<span class="hljs-variable">$_</span> <span class="hljs-operator">-match</span> <span class="hljs-string">'(d+)s+percent'</span>) {
            <span class="hljs-comment"># Only print when the percentage actually changes</span>
            <span class="hljs-built_in">Write-Host</span> <span class="hljs-string">"<span class="hljs-variable">$</span>(<span class="hljs-variable">$Matches</span>[1])% completed"</span>
        }
        <span class="hljs-keyword">else</span> {
            <span class="hljs-comment"># Just echo all over line-types, verbatim</span>
            <span class="hljs-built_in">Write-Host</span> <span class="hljs-variable">$_</span>
        }
    }
    

    Several points to note here:

    • It runs diskpart /s $tempFile: DiskPart reads and executes commands from the temporary file into the PowerShell loop for on-the-fly processing.

    • For a better user-experience: the snippet below does the trick of filtering out repeated status values by comparing $pct with the sentinel $lastPct, and only writing new lines when they differ.

    How?

    Before entering the loop, we initialize:

    <span class="hljs-variable">$lastPct</span> with <span class="hljs-literal">-1</span>
    <span class="hljs-variable">$lastPct</span> = <span class="hljs-literal">-1</span> <span class="hljs-comment"># We initiate a sentinel value</span>
    

    We are having a guaranteed “first” value that no real percent (0–100) will equal. That way, as soon as you see the first 0 percent, 10 percent, or whatever, it differs from -1.

    Then:

    <span class="hljs-keyword">if</span> (<span class="hljs-variable">$_</span> <span class="hljs-operator">-match</span> <span class="hljs-string">'(d+)s+percent'</span>) {
        <span class="hljs-comment"># Print only when the percentage changes</span>
        <span class="hljs-built_in">Write-Host</span> <span class="hljs-string">"<span class="hljs-variable">$</span>(<span class="hljs-variable">$Matches</span>[1])% completed"</span>
    }
    

    This guarantees that on the very first percentage update (say “0 percent” or “10 percent”), $pct –ne $lastPct will be true, so it emits the first line. Afterwards, $lastPct holds the last real percentage, and it only prints again when a new, different progress percentage comes in.

    The output looks more clean:

    10% completed
    20% completed
    …
    

    Otherwise, it’ll flood the screen with dozens of identical “20 percent completed” (for example) updates.

    Of course we handle the case of other values (non percent lines) normally:

    <span class="hljs-keyword">else</span> {
        <span class="hljs-comment"># non-percent lines: print verbatim</span>
        <span class="hljs-keyword">if</span> (<span class="hljs-variable">$_</span> <span class="hljs-operator">-match</span> <span class="hljs-string">'S'</span>) {
            <span class="hljs-built_in">Write-Host</span> <span class="hljs-variable">$_</span>
        }
    }
    

    Once the process is done, don’t forget to clean up the tempfile.

    <span class="hljs-built_in">Remove-Item</span> <span class="hljs-variable">$tempFile</span> <span class="hljs-literal">-ErrorAction</span> SilentlyContinue
    

    By the end of the process, you should see something like this

    Leaving DiskPart...
    

    Okay, that’s it for the scripting! If you collected all the snippets so far, just save them with a .ps1 file extension, or download the full example from this GitHub repository.

    Usage:

    You now have a complete understanding of what’s happening. Ready to get started? In Windows, open the Command Prompt or PowerShell as an administrator.

    • Navigate to the directory containing your .ps1 script.

    • Execute the script with the following command, replacing <File_name_here> with your actual file name:

    powershell.exe <span class="hljs-literal">-NoProfile</span> <span class="hljs-literal">-ExecutionPolicy</span> Bypass <span class="hljs-operator">-File</span> .<File_name_here>.ps1
    

    The -NoProfile -ExecutionPolicy Bypass parameters launch PowerShell in a clean, unrestricted environment that ignores user-specific settings and allows script execution without security restrictions. Don’t worry, in this case, it’s okay to do that.

    Wait…wait…wait…

    Screenshot of a command line interface showing the execution of a PowerShell script to compact a WSL (Windows Subsystem for Linux) distro. The script confirms the selected distro "Ubuntu" and proceeds to compact the VHDX file using DiskPart. Progress is shown in percentage increments, with final messages indicating successful completion of the compacting process.

    Well bravo! You’ve just reclaimed all that unused space inside your WSL2 (almost) hands free!

    Now, you can take it a step further by modifying this script to run completely automatically, without the confirmation prompt (step 4). You can also schedule it as a regular maintenance task using a task scheduler:

    schtasks /create /tn <span class="hljs-string">"Schedule_name"</span> /tr <span class="hljs-string">"powershell.exe -ExecutionPolicy Bypass -File C:pathtoscript.ps1"</span> /<span class="hljs-built_in">sc</span> monthly /d <span class="hljs-number">15</span> /st <span class="hljs-number">09</span>:<span class="hljs-number">00</span>
    

    This is an example for a monthly execution where /d 15 means 15th of each month and /st 09:00 is a start time set at 9 am.

    That’s it! Remember, regular maintenance, whether you do it manually or automatically, is essential to prevent unnecessary disk space usage and ensure a smooth experience with WSL.

    Thanks for reading!

    You can find a list of my current projects on GitHub.

    Source: freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More 

    Facebook Twitter Reddit Email Copy Link
    Previous ArticleKey Metrics That Can Make or Break Your Startup
    Next Article Meet CoAct-1: A Novel Multi-Agent System that Synergistically Combines GUI-based Control with Direct Programmatic Execution

    Related Posts

    Development

    PHP 8.5.0 RC 1 available for testing

    September 26, 2025
    Development

    Terraform Code Generator Using Ollama and CodeGemma

    September 26, 2025
    Leave A Reply Cancel Reply

    For security, use of Google's reCAPTCHA service is required which is subject to the Google Privacy Policy and Terms of Use.

    Continue Reading

    Spring Security Vulnerability Let Attackers Determine Which Usernames are Valid

    Security

    Overwatch 2 joins up with Street Fighter 6 in this dream-come-true collaboration

    News & Updates

    Russian Hackers Exploit Microsoft OAuth to Target Ukraine Allies via Signal and WhatsApp

    Development

    Meta AI Introduces CATransformers: A Carbon-Aware Machine Learning Framework to Co-Optimize AI Models and Hardware for Sustainable Edge Deployment

    Machine Learning

    Highlights

    Development

    Design Systems in 2025: Why They’re the Blueprint for Consistent UX

    July 24, 2025

    Discover why design systems are essential for consistent UX in 2025. Learn how top companies…

    Billions of Apple Devices at Risk from “AirBorne” AirPlay Vulnerabilities

    May 3, 2025

    How to Get User Model in Django – A Simple Guide With Examples

    April 30, 2025

    chess22k is a chess engine written in Java

    June 15, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.