Wsl.ps1


function Connect-Wsl() {
  param(
    [Parameter(Position = 0, Mandatory = $true, HelpMessage = "Enter a virtual machine name")]
    [string] $Name,
    [switch] $New
  )

  if ($New) {
    New-Wsl $Name
  }

  if (-Not(Test-WslRunning $Name)) {
    Start-Wsl $Name
  }

  wsl --distribution $Name --cd '~' --user 'box'

}

function Get-Wsl() {
  wsl -l -v
}

function New-Wsl() {
  param(
    [Parameter(Mandatory = $true, HelpMessage = "Enter a virtual machine name")]
    [string] $Name,
    [switch] $Update
  )

  $instancePath = Get-WslPath $Name


  # Check vm not registered
  
  if (Test-Path (Join-Path $instancePath "ext4.vhdx") -PathType Leaf ) {
    Write-Host -ForegroundColor Red "A virtual machine with the name '$Name' already exists."
    exit
  }

  # Get image
  
  $imagePath = Get-Ubuntu -Path "wsl/noble/current" -File "ubuntu-noble-wsl-amd64-wsl.rootfs.tar.gz" -Update $Update

  # Create config file

  $file = Get-WslConfigFile $Name
  $userData = Get-WslConfig $Name
  $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False

  [System.IO.File]::WriteAllLines($file, $userData, $Utf8NoBomEncoding)
  # Get-WslConfig | Out-File -Encoding "UTF8" $file

  # Create virtual machine

  if (-Not(Test-Path $instancePath)) { 
    mkdir -Path $instancePath | Out-Null 
  } 

  Write-Host("Importing $name ...")
  wsl --import $name $instancePath $imagePath
  # wsl --distribution $Name -- hostnamectl set-hostname $Name
}

function Remove-Wsl() {
  param(
    [Parameter(Mandatory = $true)]
    [string] $Name
  )

  wsl --unregister $Name

  $instancePath = Get-WslPath $Name
  if (Test-Path $instancePath) { 
    Remove-Item -Path $instancePath | Out-Null 
  }

  $configFile = Get-WslConfigFile $Name
  if (Test-Path $configFile) { 
    Remove-Item -Path (Get-WslConfigFile $Name) | Out-Null
  }
}

function Start-Wsl() {
  param(
    [Parameter(Position = 0, Mandatory = $true, HelpMessage = "Enter a virtual machine name")]
    [string] $Name
  )

  if (Test-WslRunning $Name) {
    Write-Host -ForegroundColor Yellow "${Name}: Is running!"
  }
  else {
    Write-Host "${Name}: Starting ..." -NoNewline
    wsl --distribution $Name --exec dbus-launch true
    Write-Host -ForegroundColor Green " Done."
  }
}

function Stop-Wsl() {
  param(
    [Parameter(Position = 0, Mandatory = $true, HelpMessage = "Enter a virtual machine name")]
    [string] $Name
  )

  wsl --terminate $Name
}


##### Private

function Get-WslConfig {
  param(
    [string] $Name
  )

  $config = @"
#cloud-config
users:
  - name: box
    groups: sudo,docker,users,netdev,audio
    sudo: ALL=(ALL) NOPASSWD:ALL
    plain_text_passwd: password
    lock_passwd: false
    shell: /bin/bash
 
write_files:
  - path: /etc/wsl.conf
    append: true
    content: |
      [user]
      default=box
      [network]
      hostname=${Name}
"@


  return $config
}

function Get-WslConfigFile {
  param(
    [string] $Name
  )

  $configDir = Join-Path $env:USERPROFILE ".cloud-init"
  if (-Not(Test-Path $configDir)) {
    mkdir $configDir
  }

  $file = Join-Path $configDir "${Name}.user-data"

  return $file
  
}

function Get-WslPath {
  param(
    [string] $Name
  )

  $path = Get-BoxPath -Path "wsl"
  if ($Name) {
    $path = Join-Path $path $Name
  }
  return $path
}

function Test-WslRunning {

  param(
    [string] $Name
  )

  $running = wsl --list --running

  return $running.Contains($Name)
}