multipass.psm1

function Connect-MultipassVM {
  <#
  .Synopsis
  Initiates a connection to a Multipass virtual machine. You can tab-complete the VMName parameter.
  #>

  [CmdletBinding()]
  param (
    [Parameter(Mandatory = $true)]
    [string] $VMName
  )
  $Interface = Find-MultipassInterface -VMName $VMName
  Write-Verbose -Message ('Connecting to SSH on IPv4 address {0}' -f $Interface)
  ssh -i "$env:windir\System32\config/systemprofile/AppData/Roaming/multipassd/ssh-keys/id_rsa" ubuntu@$Interface
}

function Test-SSHPort {
  <#
  .Synopsis
  Determines if SSH port is accessible on an IP address. Returns boolean value.
  #>

  [CmdletBinding()]
  param (
    [string] $IPAddress
  )
  Write-Verbose -Message ('Testing SSH access on {0}' -f $IPv4)
  $TcpResult = Test-Connection -TcpPort 22 -TargetName $IPAddress -IPv4
  if ($TcpResult) {
    Write-Verbose -Message ('SSH port is accessible on IPv4 address {0}' -f $IPAddress)
    return $true
  }
  else {
    Write-Verbose -Message ('SSH port is accessible on IPv4 address {0}' -f $IPAddress)
  }
}

function Find-MultipassInterface {
  <#
  .Synopsis
  Determines which virtual machine network interface is accessible from the host, by pinging it.
  #>

  [CmdletBinding()]
  param (
    [Parameter(Mandatory = $true)]
    [string] $VMName
  )
  $output = multipass info animating-seahorse --format json | ConvertFrom-Json
  foreach ($IPv4 in $output.info.$VMName.ipv4) {
    Write-Verbose -Message ('Testing IP address {0}' -f $IPv4)
    $PingResult = Test-Connection -Ping -IPv4 -TargetName $IPv4 -Count 1
    if ($PingResult.Status -eq [System.Net.NetworkInformation.IPStatus]::Success) {
      Write-Verbose -Message ('Found pingable IP address! {0}' -f $IPv4)
      if (Test-SSHPort -IPAddress $IPv4) {
        return $IPv4

      }
    }
  }
}
#Find-MultipassInterface -VMName animating-seahorse -Verbose

function Get-MultipassVM {
  <#
  .Synopsis
  Retrieves list of virtual machine names from Multipass.
  #>

  [CmdletBinding()] 
  param ()

  $Output = multipass list --format json | ConvertFrom-Json
  foreach ($VM in $Output.list) {
    Write-Output -InputObject $VM.Name
  }
}

Register-ArgumentCompleter -CommandName Connect-MultipassVM -ParameterName VMName -ScriptBlock { Get-MultipassVM }