A WSL2 instance that took hours to set up — installed packages, shell configs, SSH keys, Python environments, dotfiles — can be destroyed in seconds by a Windows reinstall, a failed upgrade, or accidentally running wsl --unregister. This guide covers how to back up a WSL2 instance with wsl --export, restore it with wsl --import, automate daily backups with Task Scheduler, and migrate a full environment to a new machine. Exact commands, expected output, and the specific errors you will run into. Tested on Windows 10 and Windows 11, March 2026.
If you have not set up WSL2 yet, start with the WSL2 installation guide first. For moving files in and out of WSL2 after restoring, the WSL file transfer guide covers every method.
How WSL2 Backup Works
wsl --export creates a tar archive of your entire Linux distribution — every file, installed package, configuration, and user data. The resulting .tar file is a complete snapshot you can import onto any Windows machine running WSL2. It is not incremental — every export is a full copy of the current state.
What is included in a WSL2 export:
- All files in the Linux filesystem — home directory, installed software, configs
- All installed packages (apt, pip, npm globally installed)
- Shell configuration —
.bashrc,.zshrc,.profile - SSH keys in
~/.ssh/ - Docker images if Docker is running inside WSL2
What is NOT included:
- Running processes — the export is a filesystem snapshot, not a live state
- Files stored on Windows drives (
/mnt/c/,/mnt/d/) — those are Windows files, back them up separately - WSL2 configuration in
C:\Users\Username\.wslconfig— this is a Windows file, copy it separately
Step 1 — Check What Distributions You Have
Open PowerShell (does not need to be elevated for this step) and list your installed distributions:
wsl -l -v
Expected output:
NAME STATE VERSION
* Ubuntu Running 2
Debian Stopped 2
The asterisk marks the default distribution. Note the exact name — you need it for the export command. The name is case sensitive: Ubuntu and ubuntu are different.
Step 2 — Export the WSL2 Distribution
Stop the distribution first. Exporting a running distribution can produce an inconsistent backup if files are being written during the export:
wsl --terminate Ubuntu
Now export to a tar file. Create a backup folder first:
mkdir C:\WSL-Backups
wsl --export Ubuntu C:\WSL-Backups\ubuntu-backup-2026-03-26.tar
Expected output — the command runs silently. On a standard Ubuntu install with development tools the export takes 1–5 minutes and produces no progress indicator. You will see a new PowerShell prompt when it finishes:
PS C:\Users\Username>
Verify the file was created and check its size:
dir C:\WSL-Backups\
Directory of C:\WSL-Backups
26/03/2026 09:14 2,341,847,040 ubuntu-backup-2026-03-26.tar
1 File(s) 2,341,847,040 bytes
A minimal Ubuntu install with a few packages is around 500MB–1GB. A full development environment with Docker images can be 5–15GB.
Errors during export
Access is denied
Error: Access is denied.
The destination folder requires elevated permissions or the path does not exist. Run PowerShell as Administrator or use a path in your user directory:
wsl --export Ubuntu "$env:USERPROFILE\Documents\ubuntu-backup.tar"
The system cannot find the file specified
Error: The system cannot find the file specified.
The distribution name in your command does not match exactly what wsl -l -v showed. Copy the name from the list output directly.
Not enough disk space
Error: There is not enough space on the disk.
Check free space on the destination drive:
Get-PSDrive C | Select-Object Used, Free
Either free up space on C: or export to a different drive: wsl --export Ubuntu D:\Backups\ubuntu-backup.tar
Reduce Backup Size Before Exporting
Before exporting, clean up package caches and temporary files inside WSL2. This can reduce backup size by 200MB–1GB on a well-used system:
wsl -d Ubuntu -- bash -c "sudo apt-get clean && sudo apt-get autoclean && rm -rf ~/.cache/pip"
If you use Docker inside WSL2 and do not need old images in the backup:
wsl -d Ubuntu -- bash -c "docker system prune -f"
Check the current size of your WSL2 filesystem before and after:
wsl -d Ubuntu -- du -sh /
3.2G /
Restore a WSL2 Backup
To restore from a backup, use wsl --import. You specify three things: the name for the restored distribution, the folder where WSL2 will store the virtual disk, and the path to your backup tar file.
Restore to the same machine (replacing existing)
If you are replacing a broken or corrupted Ubuntu installation, unregister it first. This permanently deletes all data in that WSL2 instance — only do this if you have the backup:
wsl --unregister Ubuntu
Unregistering...
The operation completed successfully.
Now import the backup:
wsl --import Ubuntu C:\WSL\Ubuntu C:\WSL-Backups\ubuntu-backup-2026-03-26.tar
C:\WSL\Ubuntu is where the virtual disk (ext4.vhdx) will be created. Create that folder first if it does not exist:
mkdir C:\WSL\Ubuntu
wsl --import Ubuntu C:\WSL\Ubuntu C:\WSL-Backups\ubuntu-backup-2026-03-26.tar
Import runs silently. Verify it worked:
wsl -l -v
NAME STATE VERSION
* Ubuntu Stopped 2
Launch it and verify your files are there:
wsl -d Ubuntu
The default user problem after import
After importing a backup with wsl --import, WSL2 defaults to logging in as root instead of your regular user. This is the most common issue people hit after a restore:
root@machine:/mnt/c/Users/Username#
Fix it by setting the default user inside WSL2. First check your username:
# Inside WSL2 as root, check your username
ls /home/
yourusername
Then set it as default — run this in PowerShell, not inside WSL2:
ubuntu config --default-user yourusername
If that command is not found (happens with some distributions), set it via /etc/wsl.conf inside WSL2:
# Inside WSL2 as root
echo -e "[user]\ndefault=yourusername" >> /etc/wsl.conf
Then restart WSL2:
# In PowerShell
wsl --shutdown
wsl -d Ubuntu
You should now land in your home directory as your regular user.
Automate Daily WSL2 Backups with Task Scheduler
Save this as C:\Scripts\wsl-backup.ps1. It backs up all your WSL2 distributions, timestamps each file, and deletes backups older than 7 days to prevent filling your drive:
# wsl-backup.ps1
# Save to C:\Scripts\wsl-backup.ps1
$BackupDir = "C:\WSL-Backups"
$KeepDays = 7
$Date = Get-Date -Format "yyyy-MM-dd"
$LogFile = "$BackupDir\backup-log.txt"
# Create backup directory if it does not exist
if (!(Test-Path $BackupDir)) {
New-Item -ItemType Directory -Path $BackupDir | Out-Null
}
function Write-Log {
param($Message)
$Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
"$Timestamp $Message" | Tee-Object -FilePath $LogFile -Append
}
Write-Log "Starting WSL2 backup"
# Get list of distributions (filter out header lines and blank lines)
$Distributions = wsl --list --quiet | Where-Object { $_ -and $_.Trim() -ne "" }
foreach ($Distro in $Distributions) {
$Distro = $Distro.Trim()
$BackupFile = "$BackupDir\$Distro-$Date.tar"
Write-Log "Backing up $Distro to $BackupFile"
# Stop the distribution for a consistent backup
wsl --terminate $Distro 2>$null
Start-Sleep -Seconds 2
wsl --export $Distro $BackupFile
if ($LASTEXITCODE -eq 0) {
$SizeMB = [math]::Round((Get-Item $BackupFile).Length / 1MB, 1)
Write-Log "SUCCESS: $Distro backed up — $SizeMB MB"
} else {
Write-Log "ERROR: $Distro backup failed with exit code $LASTEXITCODE"
}
}
# Delete backups older than $KeepDays days
Write-Log "Cleaning backups older than $KeepDays days"
Get-ChildItem -Path $BackupDir -Filter "*.tar" |
Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$KeepDays) } |
ForEach-Object {
Remove-Item $_.FullName
Write-Log "Deleted old backup: $($_.Name)"
}
Write-Log "Backup complete"
Test it manually first before scheduling:
# Run manually to test
powershell -ExecutionPolicy Bypass -File C:\Scripts\wsl-backup.ps1
# Check the log
Get-Content C:\WSL-Backups\backup-log.txt
Expected log output:
2026-03-26 02:00:01 Starting WSL2 backup
2026-03-26 02:00:03 Backing up Ubuntu to C:\WSL-Backups\Ubuntu-2026-03-26.tar
2026-03-26 02:03:47 SUCCESS: Ubuntu backed up — 2341.2 MB
2026-03-26 02:03:47 Cleaning backups older than 7 days
2026-03-26 02:03:47 Backup complete
Schedule it with Task Scheduler using PowerShell (run as Administrator):
$Action = New-ScheduledTaskAction `
-Execute "powershell.exe" `
-Argument "-ExecutionPolicy Bypass -WindowStyle Hidden -File C:\Scripts\wsl-backup.ps1"
$Trigger = New-ScheduledTaskTrigger -Daily -At "02:00"
$Settings = New-ScheduledTaskSettingsSet `
-AllowStartIfOnBatteries `
-DontStopIfGoingOnBatteries `
-StartWhenAvailable
Register-ScheduledTask `
-TaskName "WSL2-Daily-Backup" `
-Action $Action `
-Trigger $Trigger `
-Settings $Settings `
-RunLevel Highest `
-Force
Verify the task was created:
Get-ScheduledTask -TaskName "WSL2-Daily-Backup"
TaskPath TaskName State
-------- -------- -----
\ WSL2-Daily-Backup Ready
Run it immediately to confirm it works under the scheduler (not just your user session):
Start-ScheduledTask -TaskName "WSL2-Daily-Backup"
Start-Sleep -Seconds 10
Get-Content C:\WSL-Backups\backup-log.txt
Migrate WSL2 to a New Machine
Export on the old machine, copy the tar file to the new machine, import. The tar file is self-contained — no WSL2 version dependency between the two machines as long as both are running WSL2.
On the old machine
# Also save your .wslconfig if you have one
copy "$env:USERPROFILE\.wslconfig" C:\WSL-Migration\
# Export the distribution
wsl --terminate Ubuntu
wsl --export Ubuntu C:\WSL-Migration\ubuntu-migration.tar
Copy C:\WSL-Migration\ to the new machine via USB drive, network share, or cloud storage. A 3GB tar file copies to OneDrive or Google Drive and downloads on the other end without any issues.
On the new machine
# Install WSL2 if not already installed
wsl --install
# Restart after install, then import
mkdir C:\WSL\Ubuntu
wsl --import Ubuntu C:\WSL\Ubuntu C:\WSL-Migration\ubuntu-migration.tar
# Restore .wslconfig if you had one
copy C:\WSL-Migration\.wslconfig "$env:USERPROFILE\"
# Restart WSL to apply .wslconfig settings
wsl --shutdown
# Launch and verify
wsl -d Ubuntu
Fix the default user after import using the same method described in the restore section above — it will default to root on the new machine just as it does on the same machine after an import.
Verify a Backup Is Actually Restorable
A backup you have never tested restoring from is not a real backup. The tar file can be checked without doing a full restore:
# List files in the backup to confirm it is not empty or corrupt
# Run this in WSL2 (Ubuntu) not PowerShell
tar -tzf /mnt/c/WSL-Backups/ubuntu-backup-2026-03-26.tar | head -30
./
./bin
./bin/bash
./bin/cat
./etc/
./etc/hostname
./home/
./home/yourusername/
./home/yourusername/.bashrc
If the command hangs or produces an error, the tar file is corrupt. Recreate the backup. If it produces output showing your home directory and system files, the backup is intact.
For a full restore test, import it under a different name alongside your existing installation:
mkdir C:\WSL\Ubuntu-Test
wsl --import Ubuntu-Test C:\WSL\Ubuntu-Test C:\WSL-Backups\ubuntu-backup-2026-03-26.tar
wsl -d Ubuntu-Test -- ls /home/
wsl --unregister Ubuntu-Test
If ls /home/ shows your username, the backup is good. Unregister the test instance when done — it served its purpose.
For Linux system-level configuration inside your restored WSL2 instance, including swap and memory settings, see the Linux swap management guide.
Leave a Reply