<# LXS - Containers and virtualization (Windows) Description: WSL 2, Hyper-V, Docker Desktop and VirtualBox. Repo: https://git.hyko.cx/hykocx/lxs #> # Load LXS common library (colors, UI helpers, spinner, loggers, guards). # Prefers the sibling ..\lib\common.ps1 (repo checkout or installed layout) and # only hits the network when this script is run standalone. $LxsRawBase = if ($env:LXS_RAW_BASE) { $env:LXS_RAW_BASE } else { 'https://git.hyko.cx/hykocx/lxs/raw/branch/main' } if (-not $env:LXS_RAW_PLATFORM_BASE) { $env:LXS_RAW_PLATFORM_BASE = "$LxsRawBase/windows" } $LxsLibPath = if ($PSScriptRoot) { Join-Path $PSScriptRoot '..\lib\common.ps1' } else { $null } if ($LxsLibPath -and (Test-Path $LxsLibPath)) { . $LxsLibPath } else { try { $LxsLibSource = Invoke-RestMethod -Uri "$env:LXS_RAW_PLATFORM_BASE/lib/common.ps1" -UseBasicParsing -ErrorAction Stop } catch { Write-Error 'Failed to fetch lib/common.ps1' exit 1 } # The library ships with a UTF-8 BOM (Windows PowerShell 5.1 needs it to # read the file as UTF-8); over HTTP that BOM arrives as a leading U+FEFF # character, which the parser will not accept. . ([scriptblock]::Create(($LxsLibSource -replace '^\uFEFF', ''))) } $env:LXS_LOG_FILE = Join-Path (Get-LxsTempDir) 'lxs_containers.log' if (-not (Assert-LxsWindows)) { exit 1 } $LxsContainerPackages = @( @{ Name = 'Docker Desktop'; Id = 'Docker.DockerDesktop' } @{ Name = 'VirtualBox'; Id = 'Oracle.VirtualBox' } ) function Show-LxsVirtualizationStatus { Clear-Host Show-LxsBoxTop -Title 'VIRTUALIZATION STATUS' Write-Host '' try { $cs = Get-CimInstance Win32_ComputerSystem -ErrorAction Stop if ($cs.HypervisorPresent) { Write-LxsOk 'A hypervisor is running (Hyper-V, WSL 2 or another VMM)' } else { $proc = Get-CimInstance Win32_Processor -ErrorAction Stop | Select-Object -First 1 if ($proc.VirtualizationFirmwareEnabled) { Write-LxsOk 'Hardware virtualization is enabled in firmware, no hypervisor running' } else { Write-LxsWarn 'Hardware virtualization looks DISABLED in the BIOS/UEFI.' Write-Host "$($script:Gray) Enable Intel VT-x / AMD-V there, or Docker and WSL 2 will not start.$($script:NC)" } } } catch { Write-LxsWarn 'Could not read the virtualization state.' } Write-Host '' foreach ($feature in @('Microsoft-Windows-Subsystem-Linux', 'VirtualMachinePlatform', 'Microsoft-Hyper-V-All')) { try { $f = Get-WindowsOptionalFeature -Online -FeatureName $feature -ErrorAction Stop $color = if ($f.State -eq 'Enabled') { $script:Cyan } else { $script:Gray } Write-Host (" {0,-38} $color{1}$($script:NC)" -f $feature, $f.State) } catch { Write-Host (" {0,-38} $($script:Gray)not available on this edition$($script:NC)" -f $feature) } } Write-Host '' if (Get-Command wsl.exe -ErrorAction SilentlyContinue) { Write-Host "$($script:Cyan)Installed WSL distributions:$($script:NC)" & wsl.exe --list --verbose 2>&1 | Out-String | Write-Host } } function Install-LxsWsl { Clear-Host Show-LxsBoxTop -Title 'WSL 2' Write-Host '' Write-Host 'Enables WSL and the Virtual Machine Platform, then installs the' Write-Host "default distribution. A $($script:Bold)reboot is required$($script:NC) afterwards." Write-Host '' if (-not (Confirm-LxsAction -Question 'Install WSL 2?')) { Write-LxsInfo 'Cancelled.'; return } if (-not (Test-LxsAdmin)) { Write-LxsErr 'Installing WSL requires administrator rights.' return } Write-Host '' & wsl.exe --install if ($LASTEXITCODE -eq 0) { Write-LxsOk 'WSL install started - reboot to finish' } else { Write-LxsWarn "wsl --install exited with code $LASTEXITCODE" } } function Enable-LxsHyperV { Clear-Host Show-LxsBoxTop -Title 'HYPER-V' Write-Host '' Write-Host 'Enables the Hyper-V platform and management tools.' Write-Host '' Write-Host "$($script:Gray)Hyper-V is only on Pro, Enterprise and Education editions. Turning it$($script:NC)" Write-Host "$($script:Gray)on takes over the hardware virtualization extensions, which can stop$($script:NC)" Write-Host "$($script:Gray)VirtualBox and VMware from running their own VMs.$($script:NC)" Write-Host '' if (-not (Confirm-LxsAction -Question 'Enable Hyper-V?')) { Write-LxsInfo 'Cancelled.'; return } if (-not (Test-LxsAdmin)) { Write-LxsErr 'Enabling Hyper-V requires administrator rights.' return } Write-Host '' try { Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-All -All -NoRestart -ErrorAction Stop | Out-Null Write-LxsOk 'Hyper-V enabled - reboot to finish' } catch { Write-LxsErr "Could not enable Hyper-V: $($_.Exception.Message)" } } function Show-LxsContainersMenu { while ($true) { Clear-Host Show-LxsBoxTop -Title 'CONTAINERS & VM' Write-Host '' Show-LxsMenuItem '1' 'Show virtualization status' Show-LxsMenuItem '2' 'Install WSL 2' 'needs admin + reboot' Show-LxsMenuItem '3' 'Enable Hyper-V' 'needs admin + reboot' Show-LxsMenuItem '4' 'Install Docker / VirtualBox' Show-LxsMenuItem '0' 'Back' '' -Exit Write-Host '' Show-LxsBoxBottom Write-Host '' $choice = Read-LxsChoice Write-Host '' switch ($choice) { '1' { Show-LxsVirtualizationStatus; Read-LxsEnter } '2' { Install-LxsWsl; Read-LxsEnter } '3' { Enable-LxsHyperV; Read-LxsEnter } '4' { Invoke-LxsPackageMenu -Title 'CONTAINERS' -Packages $LxsContainerPackages ` -Note 'Docker Desktop needs WSL 2 or Hyper-V enabled first.' | Out-Null Read-LxsEnter } '0' { return } default { Write-LxsErr 'Invalid protocol. Select 0-4.'; Start-Sleep -Seconds 1 } } } } Show-LxsContainersMenu exit 75