Skip to content

Instantly share code, notes, and snippets.

@hizkifw
Last active August 2, 2023 01:42
Show Gist options
  • Save hizkifw/9c95af4ea11210e2fe7402fa3c59d4cf to your computer and use it in GitHub Desktop.
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
<#
.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