Last active
July 15, 2025 08:33
-
-
Save sycomix/b887f72867aaec27d0c0e6d4ddee999b to your computer and use it in GitHub Desktop.
secondary deploy script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <# | |
| .SYNOPSIS | |
| Installs a custom WSL2 distribution from a .tar file, creates a new user, | |
| and generates a Windows Terminal profile. | |
| .DESCRIPTION | |
| This script automates the final setup of a custom WSL2 distro. It handles | |
| importing the tarball, creating a specified user with sudo privileges, setting | |
| that user as the default for login, and providing a JSON snippet for easy | |
| integration into the Windows Terminal settings. | |
| .NOTES | |
| Author: Gemini | |
| Version: 1.4 | |
| Requires: An existing .tar file created by the WSL2 Distro Builder script. | |
| Changes: | |
| - Fixed CRLF line ending issue in the user creation command string. | |
| - Implemented a more robust, multi-step user creation process to ensure the home directory is created correctly. | |
| - Fixed bug where the GUID for the Windows Terminal profile was not being generated correctly. | |
| - Fixed PowerShell parsing error for variables in strings by using ${} delimiters. | |
| .PARAMETER TarPath | |
| The full path to the .tar file of the custom WSL distribution. | |
| .PARAMETER DistroName | |
| The name you want to assign to the new WSL distribution (e.g., "MyCustomOS"). | |
| .EXAMPLE | |
| .\Install-CustomWSL.ps1 -TarPath "C:\work\MyDevOS.tar" -DistroName "MyDevOS" | |
| This will start the interactive installation process for the specified distro. | |
| #> | |
| param( | |
| [Parameter(Mandatory=$true)] | |
| [string]$TarPath, | |
| [Parameter(Mandatory=$true)] | |
| [string]$DistroName | |
| ) | |
| # --- Main Script --- | |
| # Function to check if a WSL distro exists | |
| function Test-WslDistroExists { | |
| param ([string]$Name) | |
| $distros = wsl --list --quiet | |
| return $distros -contains $Name | |
| } | |
| # 1. Validate inputs and set paths | |
| if (-not (Test-Path -Path $TarPath -PathType Leaf)) { | |
| Write-Host "❌ Error: The file '$TarPath' was not found." -ForegroundColor Red | |
| exit | |
| } | |
| $InstallLocation = Join-Path $env:LOCALAPPDATA $DistroName | |
| Write-Host "Distro will be installed to: $InstallLocation" -ForegroundColor Cyan | |
| # 2. Check for existing distro and confirm overwrite | |
| if (Test-WslDistroExists -Name $DistroName) { | |
| Write-Host "⚠️ A distribution named '$DistroName' already exists." -ForegroundColor Yellow | |
| $confirm = Read-Host "Do you want to unregister and replace it? (y/n)" | |
| if ($confirm -ne 'y') { | |
| Write-Host "Installation cancelled." | |
| exit | |
| } | |
| Write-Host "Unregistering existing '$DistroName' distribution..." | |
| wsl --unregister $DistroName | |
| if ($LASTEXITCODE -ne 0) { throw "Failed to unregister the existing distribution." } | |
| # Clean up the old installation directory | |
| if (Test-Path -Path $InstallLocation) { | |
| Remove-Item -Recurse -Force $InstallLocation | |
| } | |
| } | |
| # 3. Get new user details | |
| Write-Host "`nPlease provide details for the primary user of this new distro." -ForegroundColor Cyan | |
| $UserName = Read-Host "Enter the desired username (e.g., 'syco')" | |
| if ([string]::IsNullOrEmpty($UserName)) { | |
| Write-Host "❌ Username cannot be empty. Exiting." -ForegroundColor Red | |
| exit | |
| } | |
| $Password = Read-Host -AsSecureString "Enter the password for '$UserName'" | |
| # 4. Import the new distribution | |
| Write-Host "Importing '$DistroName' from '$TarPath'..." -ForegroundColor Green | |
| New-Item -Path $InstallLocation -ItemType Directory -Force | Out-Null | |
| wsl --import $DistroName $InstallLocation $TarPath --version 2 | |
| if ($LASTEXITCODE -ne 0) { throw "Failed to import the WSL distribution." } | |
| Write-Host "✅ Import complete." | |
| # 5. Create new user and configure sudo | |
| Write-Host "Creating user '$UserName' inside the new distro..." | |
| # Convert the secure password to a plain text string for the shell command | |
| $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password) | |
| $PlainTextPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) | |
| [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($BSTR) | |
| $userSetupCommands = " | |
| set -e; | |
| useradd -m -s /bin/bash ${UserName}; | |
| echo '${UserName}:${PlainTextPassword}' | chpasswd; | |
| if getent group sudo >/dev/null; then usermod -aG sudo ${UserName}; fi; | |
| if getent group wheel >/dev/null; then usermod -aG wheel ${UserName}; fi; | |
| " | |
| # FIXED: Explicitly replace Windows (CRLF) line endings with Linux (LF) endings. | |
| $LfUserSetupCommands = $userSetupCommands.Replace("`r`n", "`n") | |
| wsl -d $DistroName -u root -- bash -c $LfUserSetupCommands | |
| if ($LASTEXITCODE -ne 0) { | |
| Write-Host "⚠️ Could not automatically create user. You may need to log in as root to create a user manually." -ForegroundColor Yellow | |
| } else { | |
| Write-Host "✅ User '$UserName' created successfully." | |
| } | |
| # 6. Set the new user as the default for login | |
| Write-Host "Setting '$UserName' as the default user..." | |
| $wslConfContent = @" | |
| [user] | |
| default=${UserName} | |
| "@ | |
| # Use a here-string with bash to correctly write the multi-line content to /etc/wsl.conf | |
| wsl -d $DistroName -u root -- bash -c "cat <<'EOF' > /etc/wsl.conf | |
| $wslConfContent | |
| EOF" | |
| if ($LASTEXITCODE -ne 0) { | |
| Write-Host "⚠️ Could not set the default user automatically." -ForegroundColor Yellow | |
| } else { | |
| Write-Host "✅ Default user set." | |
| } | |
| # 7. Generate Windows Terminal Profile | |
| Write-Host "`nGenerating Windows Terminal profile..." -ForegroundColor Green | |
| $guid = [guid]::NewGuid().ToString() | |
| $profileJson = @" | |
| { | |
| "guid": "{${guid}}", | |
| "hidden": false, | |
| "name": "${DistroName}", | |
| "commandline": "wsl.exe -d ${DistroName}", | |
| "startingDirectory": "//wsl`$/${DistroName}/home/${UserName}", | |
| "icon": "ms-appx:///ProfileIcons/{9acb9455-ca41-5af7-950f-6bca1de9727a}.png" | |
| } | |
| "@ | |
| $jsonFilePath = Join-Path $pwd "terminal-profile-for-$($DistroName).json" | |
| $profileJson | Set-Content -Path $jsonFilePath | |
| Write-Host "✅ Windows Terminal profile generated!" -ForegroundColor Magenta | |
| Write-Host "--------------------------------------------------------" | |
| Write-Host "To add this to Windows Terminal, follow these steps:" | |
| Write-Host "1. Open Windows Terminal." | |
| Write-Host "2. Go to Settings (Ctrl + ,)." | |
| Write-Host "3. Click 'Open JSON file' in the bottom-left corner." | |
| Write-Host "4. Copy the following JSON snippet and paste it into the 'list' array in your settings.json file." | |
| Write-Host " (A copy has also been saved to '$jsonFilePath')" | |
| Write-Host "--------------------------------------------------------" | |
| Write-Host $profileJson -ForegroundColor Cyan | |
| Write-Host "--------------------------------------------------------" | |
| Write-Host "`nInstallation complete. Please restart the Windows Terminal to see your new profile." -ForegroundColor Green | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment