vscode中ssh自动登录脚本
脚本作用:
在使用ssh进行远程开发的时候,一键设置windwos和远程服务器的密码
这是powershell脚本:通用命名vscode_ssh_setup.ps1
# VS Code SSH 通用配置脚本
# 此脚本用于设置Windows与Linux之间的SSH无密码登录
# 并配置VS Code的远程开发环境
# 默认设置
$defaultSettings = @{
RemoteIP = "192.168.1.252"
RemoteUser = "root"
RemotePort = 22
KeyType = "rsa"
KeySize = 4096
KeyPath = "$env:USERPROFILE\.ssh\id_rsa"
ConfigPath = "$env:USERPROFILE\.ssh\config"
}
# 显示标题
function Show-Title {
Clear-Host
Write-Host "===============================================" -ForegroundColor Cyan
Write-Host " VS Code SSH 远程开发环境配置工具" -ForegroundColor Cyan
Write-Host "===============================================" -ForegroundColor Cyan
Write-Host ""
}
# 收集用户设置
function Get-UserSettings {
Write-Host "请配置SSH连接参数(直接回车使用默认值)" -ForegroundColor Yellow
Write-Host ""
# 远程服务器IP
$remoteIP = Read-Host "远程服务器IP地址 [默认: $($defaultSettings.RemoteIP)]"
if ([string]::IsNullOrEmpty($remoteIP)) { $remoteIP = $defaultSettings.RemoteIP }
# 远程服务器用户名
$remoteUser = Read-Host "远程服务器用户名 [默认: $($defaultSettings.RemoteUser)]"
if ([string]::IsNullOrEmpty($remoteUser)) { $remoteUser = $defaultSettings.RemoteUser }
# 远程服务器端口
$remotePortInput = Read-Host "SSH端口 [默认: $($defaultSettings.RemotePort)]"
$remotePort = $defaultSettings.RemotePort
if (![string]::IsNullOrEmpty($remotePortInput)) {
try {
$remotePort = [int]$remotePortInput
} catch {
Write-Host "端口必须是数字,使用默认端口: $($defaultSettings.RemotePort)" -ForegroundColor Yellow
}
}
# 密钥类型
$keyType = Read-Host "密钥类型 (rsa/ed25519) [默认: $($defaultSettings.KeyType)]"
if ([string]::IsNullOrEmpty($keyType)) { $keyType = $defaultSettings.KeyType }
elseif ($keyType -ne "rsa" -and $keyType -ne "ed25519") {
Write-Host "不支持的密钥类型,使用默认: $($defaultSettings.KeyType)" -ForegroundColor Yellow
$keyType = $defaultSettings.KeyType
}
# 密钥大小
$keySizeInput = Read-Host "密钥大小 [RSA默认: $($defaultSettings.KeySize), ED25519无需指定]"
$keySize = $defaultSettings.KeySize
if (![string]::IsNullOrEmpty($keySizeInput) -and $keyType -eq "rsa") {
try {
$keySize = [int]$keySizeInput
} catch {
Write-Host "密钥大小必须是数字,使用默认: $($defaultSettings.KeySize)" -ForegroundColor Yellow
}
}
# 密钥位置
$keyPathSuggestion = "$env:USERPROFILE\.ssh\id_$keyType"
$keyPath = Read-Host "密钥存储位置 [默认: $keyPathSuggestion]"
if ([string]::IsNullOrEmpty($keyPath)) { $keyPath = $keyPathSuggestion }
# 返回设置
return @{
RemoteIP = $remoteIP
RemoteUser = $remoteUser
RemotePort = $remotePort
KeyType = $keyType
KeySize = $keySize
KeyPath = $keyPath
ConfigPath = $defaultSettings.ConfigPath
}
}
# 主函数
function Main {
Show-Title
$settings = Get-UserSettings
# 显示配置信息
Write-Host "`n配置信息预览:" -ForegroundColor Green
Write-Host "远程服务器: $($settings.RemoteUser)@$($settings.RemoteIP):$($settings.RemotePort)" -ForegroundColor White
Write-Host "密钥类型: $($settings.KeyType) $(if($settings.KeyType -eq 'rsa'){"($($settings.KeySize)位)"})" -ForegroundColor White
Write-Host "密钥路径: $($settings.KeyPath)" -ForegroundColor White
Write-Host "配置文件: $($settings.ConfigPath)" -ForegroundColor White
$confirm = Read-Host "`n确认以上设置并继续? (y/n) [默认: y]"
if ($confirm -eq "n") {
Write-Host "`n已取消操作" -ForegroundColor Yellow
return
}
# 确保.ssh目录存在
$sshDir = Split-Path -Path $settings.KeyPath -Parent
if (!(Test-Path $sshDir)) {
New-Item -ItemType Directory -Path $sshDir | Out-Null
Write-Host "已创建目录: $sshDir" -ForegroundColor Green
}
# 生成SSH密钥
$pubKeyPath = "$($settings.KeyPath).pub"
if (!(Test-Path $settings.KeyPath)) {
Write-Host "`n正在生成SSH密钥..." -ForegroundColor Yellow
if ($settings.KeyType -eq "rsa") {
ssh-keygen -t $settings.KeyType -b $settings.KeySize -f $settings.KeyPath -N '""'
} else {
ssh-keygen -t $settings.KeyType -f $settings.KeyPath -N '""'
}
if ($LASTEXITCODE -ne 0) {
Write-Host "密钥生成失败,错误代码: $LASTEXITCODE" -ForegroundColor Red
return
}
Write-Host "密钥生成成功!" -ForegroundColor Green
} else {
Write-Host "`n检测到密钥已存在: $($settings.KeyPath)" -ForegroundColor Cyan
}
# 读取公钥
if (Test-Path $pubKeyPath) {
$publicKey = Get-Content $pubKeyPath -Raw
Write-Host "`n公钥内容:" -ForegroundColor Yellow
Write-Host $publicKey -ForegroundColor Gray
# 上传公钥到服务器
$uploadKey = Read-Host "`n是否将公钥上传到远程服务器? (y/n) [默认: y]"
if ($uploadKey -ne "n") {
Write-Host "`n上传公钥到 $($settings.RemoteUser)@$($settings.RemoteIP)..." -ForegroundColor Yellow
# 密码认证方式
$usePassword = Read-Host "`n需要使用密码登录来上传密钥吗? (y/n) [默认: y]"
if ($usePassword -ne "n") {
# 请求输入密码(不显示在屏幕上)
$securePassword = Read-Host "请输入远程服务器密码" -AsSecureString
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($securePassword)
$password = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
[System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($BSTR)
# 创建临时脚本
$tempScriptPath = [System.IO.Path]::GetTempFileName()
$tempScriptPath = $tempScriptPath -replace ".tmp", ".sh"
"mkdir -p ~/.ssh" | Out-File -FilePath $tempScriptPath -Encoding ASCII
"chmod 700 ~/.ssh" | Out-File -FilePath $tempScriptPath -Encoding ASCII -Append
"echo `"$publicKey`" >> ~/.ssh/authorized_keys" | Out-File -FilePath $tempScriptPath -Encoding ASCII -Append
"chmod 600 ~/.ssh/authorized_keys" | Out-File -FilePath $tempScriptPath -Encoding ASCII -Append
"echo 'Public key added to authorized_keys'" | Out-File -FilePath $tempScriptPath -Encoding ASCII -Append
# 准备使用sshpass
$sshpassExists = $false
try {
$sshpassCheck = Invoke-Expression "sshpass -V" -ErrorAction SilentlyContinue
$sshpassExists = $true
} catch {
$sshpassExists = $false
}
if ($sshpassExists) {
# 使用sshpass上传
$sshPort = "-p $($settings.RemotePort)"
$remoteHost = "$($settings.RemoteUser)@$($settings.RemoteIP)"
try {
Invoke-Expression "sshpass -p `"$password`" scp $sshPort $tempScriptPath $remoteHost:/tmp/add_key.sh"
Invoke-Expression "sshpass -p `"$password`" ssh $sshPort $remoteHost 'chmod +x /tmp/add_key.sh && /tmp/add_key.sh && rm /tmp/add_key.sh'"
Write-Host "公钥已成功上传到服务器!" -ForegroundColor Green
} catch {
Write-Host "上传公钥失败: $_" -ForegroundColor Red
Write-Host "请尝试手动上传公钥" -ForegroundColor Yellow
}
} else {
# sshpass不可用,使用手动复制方式
Write-Host "`nsshpass工具未安装,请手动执行以下操作:" -ForegroundColor Yellow
Write-Host "1. 复制以下公钥内容:" -ForegroundColor White
Write-Host $publicKey -ForegroundColor Cyan
Write-Host "2. 登录到服务器: ssh $($settings.RemoteUser)@$($settings.RemoteIP) -p $($settings.RemotePort)" -ForegroundColor White
Write-Host "3. 执行以下命令:" -ForegroundColor White
Write-Host " mkdir -p ~/.ssh" -ForegroundColor Cyan
Write-Host " chmod 700 ~/.ssh" -ForegroundColor Cyan
Write-Host " echo '复制的公钥内容' >> ~/.ssh/authorized_keys" -ForegroundColor Cyan
Write-Host " chmod 600 ~/.ssh/authorized_keys" -ForegroundColor Cyan
$continue = Read-Host "`n完成手动上传后按Enter继续,或输入n取消 [默认: 继续]"
if ($continue -eq "n") {
Write-Host "已取消配置" -ForegroundColor Yellow
Remove-Item -Path $tempScriptPath -Force -ErrorAction SilentlyContinue
return
}
}
# 删除临时脚本
Remove-Item -Path $tempScriptPath -Force -ErrorAction SilentlyContinue
} else {
# 使用现有密钥尝试登录
$sshPort = "-p $($settings.RemotePort)"
$remoteHost = "$($settings.RemoteUser)@$($settings.RemoteIP)"
# 创建临时脚本
$tempScriptPath = [System.IO.Path]::GetTempFileName()
$tempScriptPath = $tempScriptPath -replace ".tmp", ".sh"
"mkdir -p ~/.ssh" | Out-File -FilePath $tempScriptPath -Encoding ASCII
"chmod 700 ~/.ssh" | Out-File -FilePath $tempScriptPath -Encoding ASCII -Append
"echo `"$publicKey`" >> ~/.ssh/authorized_keys" | Out-File -FilePath $tempScriptPath -Encoding ASCII -Append
"chmod 600 ~/.ssh/authorized_keys" | Out-File -FilePath $tempScriptPath -Encoding ASCII -Append
"echo 'Public key added to authorized_keys'" | Out-File -FilePath $tempScriptPath -Encoding ASCII -Append
try {
# 构造正确的SCP命令
$scpTarget = "$remoteHost`:/tmp/add_key.sh"
scp $sshPort $tempScriptPath $scpTarget
ssh $sshPort $remoteHost "chmod +x /tmp/add_key.sh && /tmp/add_key.sh && rm /tmp/add_key.sh"
Write-Host "公钥已成功上传到服务器!" -ForegroundColor Green
} catch {
Write-Host "上传公钥失败: $_" -ForegroundColor Red
Write-Host "请检查您的SSH连接设置或尝试手动上传" -ForegroundColor Yellow
}
# 删除临时脚本
Remove-Item -Path $tempScriptPath -Force -ErrorAction SilentlyContinue
}
}
# 配置VS Code
$configureVSCode = Read-Host "`n是否配置VS Code的SSH连接设置? (y/n) [默认: y]"
if ($configureVSCode -ne "n") {
# 确保配置文件目录存在
$configDir = Split-Path -Path $settings.ConfigPath -Parent
if (!(Test-Path $configDir)) {
New-Item -ItemType Directory -Path $configDir | Out-Null
}
# 检查配置文件是否存在
if (!(Test-Path $settings.ConfigPath)) {
"# SSH Config File" | Out-File -FilePath $settings.ConfigPath -Encoding UTF8
Write-Host "已创建SSH配置文件: $($settings.ConfigPath)" -ForegroundColor Green
}
# 读取现有配置
$configContent = ""
if (Test-Path $settings.ConfigPath) {
$configContent = Get-Content $settings.ConfigPath -Raw
}
# 构造主机名(IP或别名)
$hostName = Read-Host "`n请为此连接指定一个名称 [默认: $($settings.RemoteIP)]"
if ([string]::IsNullOrEmpty($hostName)) { $hostName = $settings.RemoteIP }
# 检查是否已存在配置
if ($configContent -match "Host\s+$hostName") {
$updateConfig = Read-Host "已存在名为 '$hostName' 的配置,是否更新? (y/n) [默认: y]"
if ($updateConfig -eq "n") {
Write-Host "已跳过VS Code配置" -ForegroundColor Yellow
return
}
# 从配置中删除现有配置
$configLines = Get-Content $settings.ConfigPath
$newConfig = @()
$skipLines = $false
foreach ($line in $configLines) {
if ($line -match "Host\s+$hostName") {
$skipLines = $true
continue
}
if ($skipLines -and $line -match "^Host\s+") {
$skipLines = $false
}
if (!$skipLines) {
$newConfig += $line
}
}
$newConfig | Out-File -FilePath $settings.ConfigPath -Encoding UTF8
Write-Host "已删除现有配置" -ForegroundColor Yellow
}
# 构造新配置
$newHostConfig = @"
Host $hostName
HostName $($settings.RemoteIP)
User $($settings.RemoteUser)
Port $($settings.RemotePort)
IdentityFile $($settings.KeyPath)
PreferredAuthentications publickey
ServerAliveInterval 60
"@
# 添加到配置文件
Add-Content -Path $settings.ConfigPath -Value $newHostConfig
Write-Host "VS Code SSH配置已更新!" -ForegroundColor Green
# 显示VS Code使用说明
Write-Host "`nVS Code连接说明:" -ForegroundColor Green
Write-Host "1. 打开VS Code" -ForegroundColor White
Write-Host "2. 按F1或Ctrl+Shift+P打开命令面板" -ForegroundColor White
Write-Host "3. 输入并选择 'Remote-SSH: Connect to Host...'" -ForegroundColor White
Write-Host "4. 选择 '$hostName'" -ForegroundColor White
}
} else {
Write-Host "错误: 找不到公钥文件 $pubKeyPath" -ForegroundColor Red
return
}
# 检查VS Code是否已安装Remote SSH扩展
Write-Host "`n检查VS Code扩展..." -ForegroundColor Yellow
$hasRemoteSSH = $false
try {
$extensions = Invoke-Expression "code --list-extensions" -ErrorAction SilentlyContinue
$hasRemoteSSH = $extensions -contains "ms-vscode-remote.remote-ssh"
} catch {
$hasRemoteSSH = $false
}
if ($hasRemoteSSH) {
Write-Host "已安装VS Code Remote-SSH扩展" -ForegroundColor Green
} else {
Write-Host "未检测到VS Code Remote-SSH扩展,请安装此扩展:" -ForegroundColor Yellow
Write-Host "1. 打开VS Code" -ForegroundColor White
Write-Host "2. 打开扩展面板 (Ctrl+Shift+X)" -ForegroundColor White
Write-Host "3. 搜索 'Remote - SSH'" -ForegroundColor White
Write-Host "4. 安装 'Remote - SSH' 扩展" -ForegroundColor White
}
# 完成
Write-Host "`n===============================================" -ForegroundColor Cyan
Write-Host " VS Code SSH 远程开发环境配置完成!" -ForegroundColor Cyan
Write-Host "===============================================" -ForegroundColor Cyan
}
# 执行主函数
Main
发表评论