Public/Connect-SSH.ps1

function Connect-SSH {
    <#
    .SYNOPSIS
        Connect to an SSH server using saved credentials or key files.
 
    .PARAMETER Target
        Server alias (from config.json) or hostname.
 
    .EXAMPLE
        Connect-SSH myserver
        cssh myserver
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, Position = 0)]
        [string]$Target
    )

    $config = Get-ScriptConfig

    if (-not $config) {
        Write-Host "Please configure config.json before using SSH commands." -ForegroundColor Red
        return
    }

    $useWSL = Test-WslAvailable
    if (-not $useWSL) {
        try {
            Import-Module Posh-SSH -ErrorAction Stop
        }
        catch {
            Write-Host "Neither WSL nor Posh-SSH is available." -ForegroundColor Red
            Write-Host "Install WSL: wsl --install" -ForegroundColor Yellow
            Write-Host "Or install Posh-SSH: Install-Module -Name Posh-SSH" -ForegroundColor Yellow
            return
        }
    }

    $ssh = Resolve-SSHTarget -Target $Target -Config $config
    if (-not $ssh) { return }

    $Server      = $ssh.Server
    $username    = $ssh.UserName
    $password    = $ssh.Password
    $cred        = $ssh.Credential
    $keyFilePath = $ssh.KeyFilePath
    $keyFile     = [bool]$keyFilePath

    if ($keyFile) {
        $winSsh = Get-Command ssh.exe -ErrorAction SilentlyContinue
        if ($winSsh) {
            Write-Host "Connecting to $Server as $username..." -ForegroundColor Cyan
            & ssh.exe -o StrictHostKeyChecking=no -o IdentitiesOnly=yes -i $keyFilePath "$username@$Server"
        }
        elseif ($useWSL) {
            Write-Host "Connecting to $Server as $username (via WSL)..." -ForegroundColor Cyan
            $escapedPath = $keyFilePath -replace '\\', '/'
            $wslKeyPath = (wsl wslpath -u "'$escapedPath'").Trim()
            wsl bash -c "ssh -o StrictHostKeyChecking=no -o IdentitiesOnly=yes -i '$wslKeyPath' $username@$Server"
        }
        else {
            Write-Host "Connecting to $Server as $username..." -ForegroundColor Cyan
            try {
                Import-Module Posh-SSH -ErrorAction Stop
                $session = New-SSHSession -ComputerName $Server -KeyFile $keyFilePath -AcceptKey
                Invoke-SSHCommand -SessionId $session.SessionId -Command "bash -l" -TimeOut 3600
                Remove-SSHSession -SessionId $session.SessionId | Out-Null
            }
            catch {
                Write-Host "Connection failed: $($_.Exception.Message)" -ForegroundColor Red
                return
            }
        }
    }
    elseif ($useWSL) {
        $hasSshpass = wsl bash -c "command -v sshpass >/dev/null 2>&1 && echo 'yes' || echo 'no'"
        if ($hasSshpass -match 'no') {
            Write-Host "Installing sshpass in WSL..." -ForegroundColor Yellow
            wsl bash -c "sudo apt-get update && sudo apt-get install -y sshpass"
        }
        wsl bash -c "SSHPASS='$password' sshpass -e ssh -o StrictHostKeyChecking=no $username@$Server"
    }
    else {
        Write-Host "Connecting to $Server as $username..." -ForegroundColor Cyan
        try {
            Import-Module Posh-SSH -ErrorAction Stop
            $session = New-SSHSession -ComputerName $Server -Credential $cred -AcceptKey
            Invoke-SSHCommand -SessionId $session.SessionId -Command "bash -l" -TimeOut 3600
            Remove-SSHSession -SessionId $session.SessionId | Out-Null
        }
        catch {
            Write-Host "Connection failed: $($_.Exception.Message)" -ForegroundColor Red
            return
        }
    }
}