tasks/60-Wsl.ps1

@{
    Id             = 'Wsl'
    DisplayName    = 'Windows Subsystem for Linux'
    Description    = 'Installs WSL if missing, refreshes the kernel, and writes ~/.wslconfig from the WslConfig section'
    WingetPackages = @('Microsoft.WSL')
    Action         = {
        [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
        param(
            [Parameter(Mandatory)]
            [System.Collections.IDictionary] $Paths
        )

        Write-Header -Name 'WSL'

        # Step 1: refresh the WSL kernel. The WSL backend itself is
        # installed via the Microsoft.WSL winget package - declared in
        # this task's WingetPackages metadata, so the install pass that
        # runs before any task action takes care of it. Initialize-Wsl
        # therefore just runs `wsl --update`; throws if WSL is not on
        # PATH at all (no winget pass happened, e.g. -WhatIf).
        Initialize-Wsl

        # Step 2: write ~/.wslconfig if a WslConfig section is configured.
        # When the config file has no WslConfig key, leave any existing
        # .wslconfig alone (the user may have hand-tuned it).
        $sections = Get-WslConfigConfig
        if ($null -eq $sections -or $sections.Count -eq 0) {
            Write-Status -Level Skip -Message ' [SKIP] No WslConfig section in the config file; .wslconfig untouched.'
            return
        }

        $target  = Join-Path $HOME '.wslconfig'
        $desired = ConvertTo-WslConfigIni -Sections $sections

        $current = if (Test-Path -Path $target -PathType Leaf) {
            (Get-Content -Path $target -Raw -Encoding UTF8)
        }
        else {
            ''
        }

        if ($current.TrimEnd() -eq $desired.TrimEnd()) {
            Write-Status -Level Info -Message " [INFO] $target already matches the configured WslConfig."
            return
        }

        if ($PSCmdlet.ShouldProcess($target, 'Write .wslconfig')) {
            # UTF-8 without BOM. Some tools choke on a BOM at the top of an
            # INI file; this avoids that, and works the same on PS 5.1 and
            # pwsh 7+.
            [System.IO.File]::WriteAllText(
                $target,
                $desired + [System.Environment]::NewLine,
                [System.Text.UTF8Encoding]::new($false)
            )
            Write-Status -Level Info -Message " [INFO] $target updated."
        }
    }
}