Skip to content

Commit e9e25ad

Browse files
Copilotntrappe-msft
andcommitted
Add user consent for Docker artifacts and improve uninstall robustness
Co-authored-by: ntrappe-msft <124631722+ntrappe-msft@users.noreply.github.com>
1 parent e95dca2 commit e9e25ad

1 file changed

Lines changed: 197 additions & 12 deletions

File tree

helpful_tools/Install-DockerCE/uninstall-docker-ce.ps1

Lines changed: 197 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,27 @@ Stop-Docker()
108108
{
109109
if (Test-Docker)
110110
{
111-
Write-Output "Stopping Docker service..."
112-
try
111+
$service = Get-Service -Name $global:DockerServiceName -ErrorAction SilentlyContinue
112+
if ($service.Status -eq 'Running')
113113
{
114-
Stop-Service -Name $global:DockerServiceName -Force -ErrorAction Stop
115-
Write-Output "Docker service stopped successfully."
114+
Write-Output "Stopping Docker service..."
115+
try
116+
{
117+
Stop-Service -Name $global:DockerServiceName -Force -ErrorAction Stop
118+
Write-Output "Docker service stopped successfully."
119+
}
120+
catch
121+
{
122+
Write-Warning "Failed to stop Docker service: $_"
123+
}
116124
}
117-
catch
125+
elseif ($service.Status -eq 'Stopped')
126+
{
127+
Write-Output "Docker service is already stopped."
128+
}
129+
else
118130
{
119-
Write-Warning "Failed to stop Docker service: $_"
131+
Write-Output "Docker service is in '$($service.Status)' state."
120132
}
121133
}
122134
else
@@ -201,17 +213,113 @@ Remove-DockerBinaries()
201213
}
202214
}
203215

216+
function
217+
Remove-DockerContainers()
218+
{
219+
Write-Output "Checking for existing Docker containers..."
220+
try
221+
{
222+
$containers = docker ps -aq 2>$null
223+
if ($containers)
224+
{
225+
$containerCount = ($containers | Measure-Object).Count
226+
$runningContainers = docker ps -q 2>$null
227+
$runningCount = if ($runningContainers) { ($runningContainers | Measure-Object).Count } else { 0 }
228+
229+
Write-Output "Found $containerCount Docker container(s) ($runningCount running)."
230+
231+
if (-not $Force)
232+
{
233+
$message = "Do you want to stop and remove all $containerCount Docker container(s)"
234+
if ($runningCount -gt 0) { $message += " (including $runningCount running)" }
235+
$message += "? (y/N)"
236+
237+
$response = Read-Host $message
238+
if ($response -ne "y" -and $response -ne "Y")
239+
{
240+
Write-Output "Skipping Docker containers removal."
241+
return
242+
}
243+
}
244+
245+
Write-Output "Stopping and removing all Docker containers..."
246+
docker stop $containers 2>$null | Out-Null
247+
docker rm -f $containers 2>$null
248+
Write-Output "Docker containers removed."
249+
}
250+
else
251+
{
252+
Write-Output "No Docker containers found."
253+
}
254+
}
255+
catch
256+
{
257+
Write-Warning "Failed to remove Docker containers: $_"
258+
}
259+
}
260+
261+
function
262+
Remove-DockerVolumes()
263+
{
264+
Write-Output "Checking for existing Docker volumes..."
265+
try
266+
{
267+
$volumes = docker volume ls -q 2>$null
268+
if ($volumes)
269+
{
270+
$volumeCount = ($volumes | Measure-Object).Count
271+
Write-Output "Found $volumeCount Docker volume(s)."
272+
273+
if (-not $Force)
274+
{
275+
$response = Read-Host "Do you want to remove all $volumeCount Docker volume(s)? (y/N)"
276+
if ($response -ne "y" -and $response -ne "Y")
277+
{
278+
Write-Output "Skipping Docker volumes removal."
279+
return
280+
}
281+
}
282+
283+
Write-Output "Removing all Docker volumes..."
284+
docker volume rm -f $volumes 2>$null
285+
Write-Output "Docker volumes removed."
286+
}
287+
else
288+
{
289+
Write-Output "No Docker volumes found."
290+
}
291+
}
292+
catch
293+
{
294+
Write-Warning "Failed to remove Docker volumes: $_"
295+
}
296+
}
297+
204298
function
205299
Remove-DockerImages()
206300
{
207301
if ($RemoveImages)
208302
{
209-
Write-Output "Removing all Docker images..."
303+
Write-Output "Checking for existing Docker images..."
210304
try
211305
{
212306
$images = docker images -q 2>$null
213307
if ($images)
214308
{
309+
$imageCount = ($images | Measure-Object).Count
310+
Write-Output "Found $imageCount Docker image(s)."
311+
312+
if (-not $Force)
313+
{
314+
$response = Read-Host "Do you want to remove all $imageCount Docker image(s)? (y/N)"
315+
if ($response -ne "y" -and $response -ne "Y")
316+
{
317+
Write-Output "Skipping Docker images removal."
318+
return
319+
}
320+
}
321+
322+
Write-Output "Removing all Docker images..."
215323
docker rmi -f $images 2>$null
216324
Write-Output "Docker images removed."
217325
}
@@ -274,7 +382,30 @@ Remove-DockerData()
274382
# Take ownership of the Docker data directory and its contents
275383
# This is needed for directories like windowsfilter which have restrictive ACLs
276384
Write-Output "Taking ownership of Docker data directory..."
277-
& takeown.exe /f $global:DockerDataPath /r /d y 2>$null | Out-Null
385+
386+
# Use Start-Process with timeout to handle hanging takeown operation
387+
$takeownProcess = Start-Process -FilePath "takeown.exe" -ArgumentList "/f", $global:DockerDataPath, "/r", "/d", "y" -WindowStyle Hidden -PassThru -RedirectStandardOutput $null -RedirectStandardError $null
388+
389+
# Wait for up to 3 minutes for takeown to complete
390+
$timeoutMinutes = 3
391+
$timeoutMs = $timeoutMinutes * 60 * 1000
392+
393+
if (-not $takeownProcess.WaitForExit($timeoutMs))
394+
{
395+
# Process is still running after timeout, kill it
396+
Write-Warning "Taking ownership is taking longer than $timeoutMinutes minutes. Terminating process..."
397+
try
398+
{
399+
$takeownProcess.Kill()
400+
$takeownProcess.WaitForExit(5000) # Wait up to 5 seconds for kill to complete
401+
}
402+
catch
403+
{
404+
Write-Warning "Failed to terminate takeown process: $_"
405+
}
406+
Write-Error "Taking ownership of Docker data directory timed out after $timeoutMinutes minutes."
407+
return
408+
}
278409

279410
# Grant full control to the current user
280411
& icacls.exe $global:DockerDataPath /grant "$env:USERNAME`:F" /t /c 2>$null | Out-Null
@@ -317,8 +448,36 @@ Remove-DockerData()
317448
}
318449

319450
function
320-
Remove-WindowsFeatures()
451+
Remove-DockerRegistryKeys()
321452
{
453+
Write-Output "Removing Docker registry keys..."
454+
455+
$registryPaths = @(
456+
"HKLM:\SYSTEM\CurrentControlSet\Services\docker",
457+
"HKLM:\SYSTEM\ControlSet002\Services\docker"
458+
)
459+
460+
foreach ($regPath in $registryPaths)
461+
{
462+
try
463+
{
464+
if (Test-Path $regPath)
465+
{
466+
Write-Output "Removing registry key: $regPath"
467+
Remove-Item $regPath -Recurse -Force
468+
Write-Output "Registry key removed: $regPath"
469+
}
470+
else
471+
{
472+
Write-Output "Registry key not found: $regPath"
473+
}
474+
}
475+
catch
476+
{
477+
Write-Warning "Failed to remove registry key $regPath`: $_"
478+
}
479+
}
480+
}
322481
if ($RemoveWindowsFeatures)
323482
{
324483
Write-Output "WARNING: Removing Windows features may affect other software on this system."
@@ -419,16 +578,42 @@ Remove-DockerCE()
419578
}
420579
}
421580

422-
# Remove images and networks first (while Docker is still running)
581+
# Remove containers, volumes, images and networks first (while Docker is still running or available)
582+
# We'll try to clean these up even if the service is stopped, as docker CLI might still work
423583
if (Test-Docker)
424584
{
425-
Remove-DockerImages
426-
Remove-DockerNetworks
585+
try
586+
{
587+
# Test if docker CLI is available and responsive
588+
$null = docker version 2>$null
589+
if ($LASTEXITCODE -eq 0)
590+
{
591+
Remove-DockerContainers
592+
Remove-DockerVolumes
593+
Remove-DockerImages
594+
Remove-DockerNetworks
595+
}
596+
else
597+
{
598+
Write-Output "Docker CLI is not responsive. Skipping container/volume/image/network cleanup."
599+
}
600+
}
601+
catch
602+
{
603+
Write-Output "Docker CLI is not available. Skipping container/volume/image/network cleanup."
604+
}
605+
}
606+
else
607+
{
608+
Write-Output "Docker service not found. Skipping container/volume/image/network cleanup."
427609
}
428610

429611
# Stop and remove Docker service
430612
Remove-DockerService
431613

614+
# Remove Docker registry keys
615+
Remove-DockerRegistryKeys
616+
432617
# Remove binaries
433618
Remove-DockerBinaries
434619

0 commit comments

Comments
 (0)