Public/Install-WslDistribution.ps1
|
<#
.SYNOPSIS Installs a WSL distribution. .DESCRIPTION This function installs a specified Windows Subsystem for Linux (WSL) distribution using wsl.exe. .PARAMETER Name The name of the WSL distribution to install (e.g., "Ubuntu-20.04", "Debian"). .PARAMETER Version The WSL version to use for the distribution (1 or 2). Default is 2. .PARAMETER InstallLocation Optional. The path to the local installation file for the distribution. If not provided, the distribution will be installed from the Microsoft Store. .COMPONENT Windows Subsystem for Linux (WSL) .EXAMPLE # Install Ubuntu 20.04 from C:\WSL\Ubuntu Install-WslDistribution -Name "Ubuntu-20.04" -Version 2 -InstallLocation "C:\WSL\Ubuntu" # Install Debian from the Microsoft Store Install-WslDistribution -Name "Debian" -Version 2 .NOTES Requires WSL to be installed. Ensure you have the necessary permissions to perform this operation. #> function Install-WslDistribution { [CmdletBinding()] param ( [Parameter(Mandatory = $false, Position = 0)] [ArgumentCompleter({ param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) Find-WslDistribution -Distribution "$wordToComplete*" | ForEach-Object { $_.Distribution } })] [Alias("Distro")] [string]$Distribution, [Parameter(Mandatory = $false, Position = 1, ValueFromPipelineByPropertyName = $true)] [ArgumentCompleter({ param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) Find-WslDistribution -Distribution "$wordToComplete*" | ForEach-Object { $_.Distribution } })] [string]$Name = $Distribution, [Parameter(Mandatory = $false, Position = 2, ValueFromPipelineByPropertyName = $true)] [ValidateSet(1, 2)] [int]$Version = 2, [Parameter(Mandatory = $false)] [switch]$EnableWsl1, [Parameter(Mandatory = $false)] [switch]$FixedVHD, [Parameter(Mandatory = $false)] [string]$FromFile, [Parameter(Mandatory = $false)] [switch]$Legacy, [Parameter(Mandatory = $false)] [switch]$NoDistribution, [Parameter(Mandatory = $false)] [switch]$NoLaunch, [Parameter(Mandatory = $false)] [long]$VHDSize, [Parameter(Mandatory = $false)] [string]$URLDownload, [Parameter(Mandatory = $false)] [ArgumentCompleter({ param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) Invoke-WslCommand -Command "ls $wordToComplete*" })] [string]$Location ) if ((-not $Distribution) -and (-not $Name)) { throw (New-WslErrorRecord @{ Message = "Missing required distribution name." ErrorId = "PowerShellWSLInstallMissingName" Distribution = $Distribution WslArgs = $null ExitCode = $null StdErr = $null WslVersion = (Get-WslStatus -ErrorAction SilentlyContinue).WSL }) } else { if (-not $Distribution) { $Distribution = $Name } } $WslArgs = $PSBoundParameters.GetEnumerator() | Remove-StdPsArgsParameter -ArgToRemove @('Distribution') | Convert-PsArgsToWsl # Check if the distribution is already installed $ExistingDistro = Get-WslDistribution -Distribution $Distribution -ErrorAction SilentlyContinue if ($ExistingDistro) { throw (New-WslErrorRecord @{ Message = "WSL distribution is already installed." ErrorId = "PowerShellWSLInstallAlreadyInstalled" Distribution = $Distribution WslArgs = (@('--install', $Distribution) + $WslArgs) -join ' ' ExitCode = $null StdErr = $null WslVersion = (Get-WslStatus -ErrorAction SilentlyContinue).WSL }) } $AvailableDistro = Find-WslDistribution -Distribution $Distribution -ErrorAction SilentlyContinue if (-not $AvailableDistro) { throw (New-WslErrorRecord @{ Message = "WSL distribution is not available for installation." ErrorId = "PowerShellWSLInstallDistributionUnavailable" Distribution = $Distribution WslArgs = (@('--install', $Distribution) + $WslArgs) -join ' ' ExitCode = $null StdErr = $null WslVersion = (Get-WslStatus -ErrorAction SilentlyContinue).WSL }) } Write-Information "Installing WSL distribution '$Distribution' from $(if ($Location) { "'$Location'" } else { "Microsoft Store" })..." $StdErr, $WslOutput, $Res = Invoke-WslCmdWrapper -WslArgs @('--install', $Distribution) + $WslArgs -ErrorAction Stop if ($Res -ne 0) { throw (New-WslErrorRecord @{ Message = "Failed to install WSL distribution with message: '$StdErr'" ErrorId = "PowerShellWSLInstallFailed" Distribution = $Distribution WslArgs = (@('--install', $Distribution) + $WslArgs) -join ' ' ExitCode = $Res StdErr = ($StdErr | Out-String).Trim() WslVersion = (Get-WslStatus -ErrorAction SilentlyContinue).WSL }) } Write-Information "Installation of '$Distribution' completed successfully." } |