Functions/GenXdev.AI/EnsureDockerDesktop.ps1
################################################################################ <# .SYNOPSIS Ensures Docker Desktop is installed and available for containerization operations. .DESCRIPTION Verifies if Docker Desktop is installed and properly configured on the system. If not found, installs Docker Desktop using WinGet and handles the complete installation process automatically. .EXAMPLE EnsureDockerDesktop Ensures Docker Desktop is installed and properly configured. #> function EnsureDockerDesktop { [CmdletBinding()] param() begin { ######################################################################## <# .SYNOPSIS Checks if the WinGet PowerShell module is installed. .DESCRIPTION Attempts to import the Microsoft.WinGet.Client module and verifies its presence. .EXAMPLE IsWinGetInstalled #> function IsWinGetInstalled { # attempt to load the winget module silently Microsoft.PowerShell.Core\Import-Module "Microsoft.WinGet.Client" ` -ErrorAction SilentlyContinue # verify if module was loaded successfully $module = Microsoft.PowerShell.Core\Get-Module "Microsoft.WinGet.Client" ` -ErrorAction SilentlyContinue return $null -ne $module } ######################################################################## <# .SYNOPSIS Installs the WinGet PowerShell module. .DESCRIPTION Installs and imports the Microsoft.WinGet.Client module for package management. .EXAMPLE InstallWinGet #> function InstallWinGet { # install and import winget module with force to ensure success Microsoft.PowerShell.Utility\Write-Verbose "Installing WinGet PowerShell client..." $null = PowerShellGet\Install-Module "Microsoft.WinGet.Client" -Force -AllowClobber # load the newly installed module Microsoft.PowerShell.Core\Import-Module "Microsoft.WinGet.Client" } } process { # verify if docker desktop is available in current session if (@(Microsoft.PowerShell.Core\Get-Command 'docker.exe' -ErrorAction SilentlyContinue).Length -eq 0) { # check if docker desktop is installed but not in PATH $dockerPaths = @( "${env:ProgramFiles}\Docker\Docker\resources\bin", "${env:LOCALAPPDATA}\Programs\Docker\Docker\resources\bin" ) $dockerFound = $false foreach ($path in $dockerPaths) { if (Microsoft.PowerShell.Management\Test-Path (Microsoft.PowerShell.Management\Join-Path $path "docker.exe")) { $currentPath = [Environment]::GetEnvironmentVariable('PATH', 'User') if ($currentPath -notlike "*$path*") { Microsoft.PowerShell.Utility\Write-Verbose "Adding Docker to system PATH..." [Environment]::SetEnvironmentVariable( 'PATH', "$currentPath;$path", 'User') # update current session's path $env:PATH = [Environment]::GetEnvironmentVariable('PATH', 'User') } $dockerFound = $true break } } # check if docker is now accessible if (@(Microsoft.PowerShell.Core\Get-Command 'docker.exe' -ErrorAction SilentlyContinue).Length -eq 0) { Microsoft.PowerShell.Utility\Write-Host "Docker Desktop not found. Installing Docker Desktop..." # ensure winget is available for installation if (-not (IsWinGetInstalled)) { InstallWinGet } # install docker desktop using winget package manager $null = Microsoft.WinGet.Client\Install-WinGetPackage -Id 'Docker.DockerDesktop' -Force # re-check docker paths after installation foreach ($path in $dockerPaths) { if (Microsoft.PowerShell.Management\Test-Path (Microsoft.PowerShell.Management\Join-Path $path "docker.exe")) { $currentPath = [Environment]::GetEnvironmentVariable('PATH', 'User') if ($currentPath -notlike "*$path*") { Microsoft.PowerShell.Utility\Write-Verbose "Adding Docker to system PATH..." [Environment]::SetEnvironmentVariable( 'PATH', "$currentPath;$path", 'User') # update current session's path $env:PATH = [Environment]::GetEnvironmentVariable('PATH', 'User') } break } } # verify successful installation if (-not (Microsoft.PowerShell.Core\Get-Command 'docker.exe' -ErrorAction SilentlyContinue)) { throw "Docker Desktop installation failed." } } } # ensure docker desktop service is running $dockerDesktopProcess = Microsoft.PowerShell.Management\Get-Process "Docker Desktop" -ErrorAction SilentlyContinue if (-not $dockerDesktopProcess) { Microsoft.PowerShell.Utility\Write-Host "Starting Docker Desktop..." $dockerExePath = Microsoft.PowerShell.Core\Get-Command "Docker Desktop.exe" -ErrorAction SilentlyContinue if ($dockerExePath) { Microsoft.PowerShell.Management\Start-Process $dockerExePath.Source Microsoft.PowerShell.Utility\Start-Sleep 30 } else { # try common installation paths $dockerDesktopPaths = @( "${env:ProgramFiles}\Docker\Docker\Docker Desktop.exe", "${env:LOCALAPPDATA}\Programs\Docker\Docker\Docker Desktop.exe" ) foreach ($path in $dockerDesktopPaths) { if (Microsoft.PowerShell.Management\Test-Path $path) { Microsoft.PowerShell.Management\Start-Process $path Microsoft.PowerShell.Utility\Start-Sleep 30 break } } } } # wait for docker daemon to be ready Microsoft.PowerShell.Utility\Write-Verbose "Waiting for Docker daemon to be ready..." $timeout = 60 $elapsed = 0 do { Microsoft.PowerShell.Utility\Start-Sleep -Seconds 2 $elapsed += 2 $dockerInfo = docker info 2>$null } while (-not $dockerInfo -and $elapsed -lt $timeout) if ($elapsed -ge $timeout) { throw "Docker daemon failed to start within $timeout seconds." } Microsoft.PowerShell.Utility\Write-Verbose "✅ Docker Desktop is ready." } end { } } ################################################################################ |