You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过SSH协议使用PowerShell实现远程电脑重启并等待完成

如何通过SSH协议使用PowerShell实现远程电脑重启并等待完成

刚好碰到过类似的需求,给你分享个可行的方案!因为Restart-Computer-Wait参数确实只支持WinRM,所以咱们得自己实现SSH环境下的重启+等待逻辑,步骤其实不难:

前提准备

首先得确保几个基础条件:

  • 目标电脑已经开启SSH服务,防火墙允许22端口入站
  • 你本地用的是PowerShell 7及以上版本(只有这个版本原生支持SSH作为远程协议)
  • 远程SSH账号拥有管理员权限(毕竟重启电脑需要权限)

实现思路

先通过SSH远程发送重启命令,然后循环检测远程主机的SSH服务是否恢复正常——毕竟ping通不代表SSH服务已经启动,直接检测SSH连接才是最准确的。

具体脚本实现

单次执行的简易版本

# 定义参数
$remoteHost = "你的远程主机名/IP"
$userName = "远程SSH账号"
$waitInterval = 10  # 每次检测间隔10秒
$maxRetries = 30    # 最多等待5分钟(30*10秒)

# 第一步:发送远程重启命令
try {
    Invoke-Command -HostName $remoteHost -UserName $userName -ScriptBlock { Restart-Computer -Force } -ErrorAction Stop
    Write-Host "已向 $remoteHost 发送强制重启命令"
}
catch {
    Write-Error "发送重启命令失败:$_"
    exit 1
}

# 第二步:循环等待SSH连接恢复
$retryCount = 0
$isRestartCompleted = $false

while ($retryCount -lt $maxRetries -and -not $isRestartCompleted) {
    Start-Sleep -Seconds $waitInterval
    $retryCount++
    Write-Host "等待重启中... 第 $retryCount 次尝试(剩余 $($maxRetries - $retryCount) 次)"

    try {
        # 先测试SSH端口是否开放
        $tcpClient = New-Object System.Net.Sockets.TcpClient
        $tcpClient.Connect($remoteHost, 22)
        $tcpClient.Close()

        # 再尝试建立SSH会话,确认服务正常
        $session = New-PSSession -HostName $remoteHost -UserName $userName -ErrorAction Stop
        Remove-PSSession $session

        $isRestartCompleted = $true
        Write-Host "✅ $remoteHost 重启完成,SSH连接已恢复!"
    }
    catch {
        Write-Host "⚠️ $remoteHost 暂未恢复:$($_.Exception.Message)"
    }
}

# 超时处理
if (-not $isRestartCompleted) {
    Write-Error "❌ $remoteHost 重启超时,超过 $($maxRetries*$waitInterval) 秒未恢复SSH连接"
    exit 1
}

可复用的函数版本

如果需要多次使用,可以把逻辑封装成函数:

function Restart-RemoteComputerViaSSH {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true, HelpMessage="远程主机名或IP")]
        [string]$HostName,
        
        [Parameter(Mandatory=$true, HelpMessage="远程SSH账号")]
        [string]$UserName,
        
        [Parameter(HelpMessage="检测间隔(秒)")]
        [int]$WaitInterval = 10,
        
        [Parameter(HelpMessage="最大重试次数")]
        [int]$MaxRetries = 30
    )

    # 发送重启命令
    try {
        Invoke-Command -HostName $HostName -UserName $UserName -ScriptBlock { Restart-Computer -Force } -ErrorAction Stop
        Write-Host "已向 $HostName 发送强制重启命令"
    }
    catch {
        Write-Error "发送重启命令失败:$_"
        return
    }

    # 等待重启完成
    $retryCount = 0
    $isOnline = $false

    while ($retryCount -lt $MaxRetries -and -not $isOnline) {
        Start-Sleep -Seconds $WaitInterval
        $retryCount++
        Write-Verbose "等待重启中... 第 $retryCount 次尝试"

        try {
            # 测试SSH端口
            $tcpClient = New-Object System.Net.Sockets.TcpClient
            $tcpClient.Connect($HostName, 22)
            $tcpClient.Close()

            # 验证会话可建立
            $session = New-PSSession -HostName $HostName -UserName $UserName -ErrorAction Stop
            Remove-PSSession $session

            $isOnline = $true
            Write-Host "✅ $HostName 重启完成!"
        }
        catch {
            Write-Verbose "$HostName 未恢复:$($_.Exception.Message)"
        }
    }

    if (-not $isOnline) {
        Write-Error "❌ $HostName 重启超时,超过 $($MaxRetries*$WaitInterval) 秒未恢复"
    }
}

# 使用示例(加-Verbose可以看详细日志)
Restart-RemoteComputerViaSSH -HostName "RemotePC01" -UserName "AdminUser" -Verbose

一些注意事项

  • 如果目标电脑重启速度较慢,可以适当调大$MaxRetries或者$WaitInterval参数
  • 如果你已经配置了SSH密钥免密登录,就不用每次输入密码了,脚本会自动使用密钥认证
  • 执行Restart-Computer -Force会强制关闭所有正在运行的程序,如果你需要优雅重启,可以去掉-Force参数,但可能会因为程序未响应导致重启延迟

备注:内容来源于stack exchange,提问作者Jellyfish

火山引擎 最新活动