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 } $servers = @{} $serverKeyFiles = @{} $serverUsers = @{} if ($config.ssh.servers) { foreach ($key in $config.ssh.servers.PSObject.Properties.Name) { $servers[$key] = $config.ssh.servers.$key.hostname if ($config.ssh.servers.$key.keyFile) { $serverKeyFiles[$key] = $config.ssh.servers.$key.keyFile } if ($config.ssh.servers.$key.user) { $serverUsers[$key] = $config.ssh.servers.$key.user } } } $keyFile = $null $configUser = $null if ($servers.ContainsKey($Target)) { $Server = $servers[$Target] if ($serverKeyFiles.ContainsKey($Target)) { $keyFile = $serverKeyFiles[$Target] } if ($serverUsers.ContainsKey($Target)) { $configUser = $serverUsers[$Target] } } else { $Server = $Target } $useWSL = $false $wsl = Get-Command wsl -ErrorAction SilentlyContinue if ($wsl) { $wslCheck = wsl echo "ok" 2>&1 if ($wslCheck -eq "ok") { $useWSL = $true } } 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 } } $credsDir = Join-Path $script:ToolkitRoot "creds" $keyFilePath = $null if ($keyFile) { if ([System.IO.Path]::IsPathRooted($keyFile)) { $keyFilePath = $keyFile } else { $keyFilePath = Join-Path $credsDir $keyFile } if (-not (Test-Path $keyFilePath)) { Write-Host "Key file not found: $keyFilePath" -ForegroundColor Red return } } $username = $null $password = $null $cred = $null if (-not $keyFile) { $credFile = $config.ssh.credentialFile if (-not $credFile) { $credFile = "ssh-credentials.xml" } $credPath = Join-Path $credsDir $credFile if (-not (Test-Path $credPath)) { Write-Host "Credential file not found: $credPath" -ForegroundColor Red return } $cred = Import-Clixml $credPath $username = $cred.UserName $password = $cred.GetNetworkCredential().Password } else { if ($configUser) { $username = $configUser } else { $credFile = $config.ssh.credentialFile if ($credFile) { $credPath = Join-Path $credsDir $credFile if (Test-Path $credPath) { $cred = Import-Clixml $credPath $username = $cred.UserName } } } if (-not $username) { Write-Host "Username required. Add 'user' to server config in config.json" -ForegroundColor Red return } } 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 } } } |