Last active
August 2, 2023 01:42
-
-
Save hizkifw/9c95af4ea11210e2fe7402fa3c59d4cf to your computer and use it in GitHub Desktop.
PowerShell script to prune images and compact Docker Desktop's VHDX disk on Windows
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.SYNOPSIS | |
Prune and compact the Docker VHDX disk file | |
#> | |
# Check if running as administrator | |
$CurrentUser = New-Object Security.Principal.WindowsPrincipal ` | |
$([Security.Principal.WindowsIdentity]::GetCurrent()) | |
if (-not $CurrentUser.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { | |
# Restart as administrator | |
Start-Process powershell.exe -Verb RunAs -ArgumentList $MyInvocation.MyCommand.Definition | |
exit 0 | |
} | |
# Get the path to the Docker VHDX disk file | |
$VHDBase = (Get-ChildItem HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss\ ` | |
| Where-Object { $_.GetValue("DistributionName") -eq "docker-desktop-data" } ` | |
).GetValue("BasePath").Substring(4) | |
$VHDFile = Join-Path $VHDBase "ext4.vhdx" | |
$DockerAppPath = Get-ItemPropertyValue ` | |
-Path 'HKLM:\SOFTWARE\Docker Inc.\Docker\1.0\' ` | |
-Name AppPath | |
$DockerBinPath = Get-ItemPropertyValue ` | |
-Path 'HKLM:\SOFTWARE\Docker Inc.\Docker\1.0\' ` | |
-Name BinPath | |
$DockerDesktopEXE = Join-Path $DockerAppPath "Docker Desktop.exe" | |
$DockerCLIEXE = Join-Path $DockerBinPath "docker.exe" | |
# Make sure Docker is running | |
Write-Host "Checking if Docker is running..." -ForegroundColor Yellow | |
$DockerRunning = (Get-Process -Name "Docker Desktop" -ErrorAction SilentlyContinue) | |
$DockerInitiallyRunning = $DockerRunning | |
if ($null -eq $DockerRunning) { | |
# Start Docker if not running | |
Write-Host "Docker is not running. Starting Docker..." -ForegroundColor Yellow | |
Start-Process -FilePath $DockerDesktopEXE | |
} | |
# Wait for Docker to start | |
Write-Host "Waiting for Docker to start..." -ForegroundColor Yellow | |
$DockerRunning = $false | |
while (-not $DockerRunning) { | |
docker ps > $null 2>&1 | |
$DockerRunning = $LASTEXITCODE -eq 0 | |
Start-Sleep -Seconds 1 | |
} | |
# Prune system | |
Write-Host "Running command: docker system prune -f" -ForegroundColor Yellow | |
& "$DockerCLIEXE" system prune -f | |
# Stop Docker | |
Write-Host "Stopping Docker..." -ForegroundColor Yellow | |
Get-Process -Name "Docker Desktop" | Stop-Process | |
# Stop WSL | |
Write-Host "Stopping WSL..." -ForegroundColor Yellow | |
wsl --shutdown | |
# Compact the VHDX disk file | |
Write-Host "Running diskpart on $VHDFile" -ForegroundColor Yellow | |
# Create temp file | |
$TempFile = New-TemporaryFile | |
# Write script to temp file | |
@" | |
select vdisk file="$VHDFile" | |
compact vdisk | |
exit | |
"@ | Out-File -Encoding utf8 -FilePath $TempFile.FullName | |
# Get pre-compact disk size | |
$SizePre = (Get-ChildItem $VHDFile).Length | |
$SizePreGb = [math]::round($SizePre / 1Gb, 2) | |
# Run diskpart | |
diskpart /s $TempFile.FullName | |
# Delete temp file | |
Remove-Item $TempFile.FullName | |
# Get post-compact disk size and compare | |
$SizePost = (Get-ChildItem $VHDFile).Length | |
$SizePostGb = [math]::round($SizePost / 1Gb, 2) | |
$SizeDiff = $SizePre - $SizePost | |
$SizeDiffGb = [math]::round($SizeDiff / 1Gb, 2) | |
# Restart Docker Desktop | |
if ($null -ne $DockerInitiallyRunning) { | |
Write-Host "Starting Docker..." -ForegroundColor Yellow | |
Start-Process -FilePath $DockerDesktopEXE | |
} | |
Write-Host "Done!" -ForegroundColor Green | |
Write-Host "$SizePreGb GB -> $SizePostGb GB (saved $SizeDiffGb GB)" -ForegroundColor Green | |
pause |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment