@@ -369,6 +369,30 @@ Remove-DockerNetworks()
369369 }
370370}
371371
372+ function
373+ Stop-WindowsContainerServices ()
374+ {
375+ # Stop additional Windows Container services that might be locking files
376+ $services = @ (" cexecsvc" , " vmcompute" , " vmicguestinterface" , " vmicheartbeat" , " vmickvpexchange" , " vmicrdv" , " vmicshutdown" , " vmictimesync" , " vmicvmsession" , " vmicvss" )
377+
378+ foreach ($serviceName in $services )
379+ {
380+ $service = Get-Service - Name $serviceName - ErrorAction SilentlyContinue
381+ if ($service -and $service.Status -eq ' Running' )
382+ {
383+ Write-Output " Stopping $serviceName service..."
384+ try
385+ {
386+ Stop-Service - Name $serviceName - Force - ErrorAction SilentlyContinue
387+ }
388+ catch
389+ {
390+ # Ignore errors for services we can't stop
391+ }
392+ }
393+ }
394+ }
395+
372396function
373397Remove-DockerData ()
374398{
@@ -377,8 +401,45 @@ Remove-DockerData()
377401 if (Test-Path $global :DockerDataPath )
378402 {
379403 Write-Output " Removing Docker data directory..."
404+
405+ # Stop additional services that might be locking container files
406+ Stop-WindowsContainerServices
407+
408+ # Wait a moment for services to fully stop
409+ Start-Sleep - Seconds 2
410+
380411 try
381412 {
413+ # Special handling for windowsfilter directory which is often problematic
414+ $windowsFilterPath = Join-Path $global :DockerDataPath " windowsfilter"
415+ if (Test-Path $windowsFilterPath )
416+ {
417+ Write-Output " Removing windowsfilter directory with special handling..."
418+
419+ # First, try to empty the windowsfilter directory using robocopy purge
420+ # This can sometimes handle locked files better than Remove-Item
421+ $tempEmptyDir = Join-Path $env: TEMP " EmptyDir_$ ( Get-Random ) "
422+ New-Item - ItemType Directory - Path $tempEmptyDir - Force | Out-Null
423+
424+ try
425+ {
426+ # Use robocopy to mirror an empty directory (effectively purging)
427+ & robocopy.exe $tempEmptyDir $windowsFilterPath / MIR / R:1 / W:1 / NP / NFL / NDL / NJH / NJS 2> $null | Out-Null
428+ Remove-Item $tempEmptyDir - Force - ErrorAction SilentlyContinue
429+ }
430+ catch
431+ {
432+ # If robocopy fails, continue with other methods
433+ Remove-Item $tempEmptyDir - Force - ErrorAction SilentlyContinue
434+ }
435+
436+ # Try to remove using rd command which can handle some locked files
437+ if (Test-Path $windowsFilterPath )
438+ {
439+ & cmd.exe / c " rd /s /q `" $windowsFilterPath `" " 2> $null | Out-Null
440+ }
441+ }
442+
382443 # Take ownership of the Docker data directory and its contents
383444 # This is needed for directories like windowsfilter which have restrictive ACLs
384445 Write-Output " Taking ownership of Docker data directory..."
@@ -403,25 +464,84 @@ Remove-DockerData()
403464 {
404465 Write-Warning " Failed to terminate takeown process: $_ "
405466 }
406- Write-Error " Taking ownership of Docker data directory timed out after $timeoutMinutes minutes."
407- return
467+ Write-Warning " Taking ownership of Docker data directory timed out after $timeoutMinutes minutes."
468+ # Continue with removal attempt even if takeown timed out
408469 }
409470
410471 # Grant full control to the current user
411472 & icacls.exe $global :DockerDataPath / grant " $env: USERNAME `:F" / t / c 2> $null | Out-Null
412473
413- # Now attempt to remove the directory
414- Remove-Item $global :DockerDataPath - Recurse - Force
474+ # Try multiple methods to remove the directory
475+ $removalSuccess = $false
476+
477+ # Method 1: PowerShell Remove-Item
478+ try
479+ {
480+ Remove-Item $global :DockerDataPath - Recurse - Force - ErrorAction Stop
481+ $removalSuccess = $true
482+ Write-Output " Docker data directory removed using Remove-Item."
483+ }
484+ catch
485+ {
486+ Write-Warning " Remove-Item failed: $_ "
487+ }
488+
489+ # Method 2: If PowerShell failed, try rd command
490+ if (-not $removalSuccess -and (Test-Path $global :DockerDataPath ))
491+ {
492+ try
493+ {
494+ & cmd.exe / c " rd /s /q `" $global :DockerDataPath `" "
495+ if (-not (Test-Path $global :DockerDataPath ))
496+ {
497+ $removalSuccess = $true
498+ Write-Output " Docker data directory removed using rd command."
499+ }
500+ }
501+ catch
502+ {
503+ Write-Warning " rd command failed: $_ "
504+ }
505+ }
506+
507+ # Method 3: If still exists, try robocopy purge on the entire directory
508+ if (-not $removalSuccess -and (Test-Path $global :DockerDataPath ))
509+ {
510+ try
511+ {
512+ $tempEmptyDir = Join-Path $env: TEMP " EmptyDir_$ ( Get-Random ) "
513+ New-Item - ItemType Directory - Path $tempEmptyDir - Force | Out-Null
514+
515+ # Use robocopy to mirror an empty directory over the Docker data directory
516+ & robocopy.exe $tempEmptyDir $global :DockerDataPath / MIR / R:1 / W:1 / NP / NFL / NDL / NJH / NJS 2> $null | Out-Null
517+
518+ # Then remove the now-empty directory
519+ Remove-Item $global :DockerDataPath - Force - ErrorAction SilentlyContinue
520+ Remove-Item $tempEmptyDir - Force - ErrorAction SilentlyContinue
521+
522+ if (-not (Test-Path $global :DockerDataPath ))
523+ {
524+ $removalSuccess = $true
525+ Write-Output " Docker data directory removed using robocopy purge."
526+ }
527+ }
528+ catch
529+ {
530+ Write-Warning " robocopy purge failed: $_ "
531+ Remove-Item $tempEmptyDir - Force - ErrorAction SilentlyContinue
532+ }
533+ }
415534
416- # Sanity check: Verify the Docker folder no longer exists
535+ # Final sanity check: Verify the Docker folder no longer exists
417536 if (Test-Path $global :DockerDataPath )
418537 {
419- Write-Warning " Docker data directory still exists after removal attempt: $global :DockerDataPath "
420- Write-Warning " You may need to manually remove $global :DockerDataPath "
538+ Write-Warning " Docker data directory still exists after all removal attempts: $global :DockerDataPath "
539+ Write-Warning " The windowsfilter subdirectory may still be in use by Windows Container services."
540+ Write-Warning " You may need to restart your system and manually remove $global :DockerDataPath "
421541 }
422542 else
423543 {
424- Write-Output " Docker data directory removed."
544+ Write-Output " Docker data directory successfully removed."
425545 }
426546 }
427547 catch
0 commit comments