Public/Assert-Wsl2Ready.ps1

function Assert-Wsl2Ready {
    <#
    .SYNOPSIS
        Ensures WSL2 is installed and at least one distro is registered.
        Installs WSL2 and throws a Wsl2NotReady error if not ready.
 
    .DESCRIPTION
        Callers that depend on WSL2 (wsl --mount, wsl -u root, ...) use this
        to gate execution. Behavior:
 
          1. Detect wsl.exe on PATH.
          2. Detect at least one registered distro via 'wsl --list --quiet'.
             Both are required because wsl -u root -e sh has no distro to
             target otherwise.
          3. If either is missing, run 'wsl --install' and throw an error
             whose message starts with 'Wsl2NotReady: '. The caller is
             expected to catch that prefix and exit cleanly (typically with
             a reboot prompt).
 
        Why throw rather than exit:
          - Keeps this function unit-testable. An earlier version called
            exit 0 directly, which terminated the test runner process.
 
        Why 'wsl --install' is safe to call unconditionally when not ready:
          - On Windows 11 it is idempotent: it enables the
            'Windows Subsystem for Linux' and 'Virtual Machine Platform'
            features if absent, and installs Ubuntu as the default distro.
          - Running as Administrator (already required by callers that
            need wsl --mount) is sufficient; no separate elevation prompt
            is shown.
 
    .EXAMPLE
        try {
            Assert-Wsl2Ready
            # ... WSL-dependent work ...
        }
        catch {
            if ($_.Exception.Message -match '^Wsl2NotReady: ') {
                Write-Host ($_.Exception.Message -replace '^Wsl2NotReady: ','') `
                    -ForegroundColor Yellow
                exit 0
            }
            throw
        }
    #>

    [CmdletBinding()]
    param()

    $wslExe   = Get-Command 'wsl.exe' -ErrorAction SilentlyContinue
    $wslReady = $false
    if ($null -ne $wslExe) {
        # A distro must exist; wsl -u root -e sh requires one.
        $distroList = wsl --list --quiet 2>&1
        $wslReady   = ($LASTEXITCODE -eq 0) -and ("$distroList" -match '\S')
    }

    if ($wslReady) { return }

    Write-Host " WSL2 is not ready - installing now ..." -ForegroundColor Cyan
    wsl --install
    Write-Host ""
    throw (
        "Wsl2NotReady: WSL2 has been installed. A reboot may be required " +
        "to complete setup. Please reboot and re-run the operation."
    )
}