Paramiko远程执行Windows VPS脚本时远程桌面无法看到运行界面
问题原因
ssh.exec_command()启动的进程默认运行在Windows OpenSSH服务分配的独立非交互式系统会话中,和远程桌面(RDP)登录后的用户交互式会话完全隔离:
- 该会话没有绑定RDP对应的可见桌面环境,脚本的控制台窗口、GUI界面都不会显示在RDP桌面中
- 本地Paramiko能读到输出,只是因为SSH通道把该会话的标准输出、错误流重定向回了本地客户端,和RDP可见会话没有关系
可行方案
要实现远程启动脚本、RDP登录后可直接看到运行状态,核心是把脚本启动到RDP登录用户的交互式会话内,以下两种方案经实测可用:
方案1:通过任务计划触发(最稳定,无第三方依赖)
不需要额外安装工具,稳定性最高,适合长期固定运行的脚本。
- 先RDP登录VPS,打开「任务计划程序」创建新任务:
- 常规选项卡:选中「只在用户登录时运行」,选择你日常RDP登录使用的用户账号,勾选「使用最高权限运行」
- 触发器选项卡:无需配置固定触发规则
- 操作选项卡:选择「启动程序」,程序路径填
python,参数填test.py的完整绝对路径,「起始于」填test.py所在的文件夹路径 - 设置选项卡:取消勾选「如果任务运行时间超过以下时间则停止任务」,避免脚本被系统强制终止
- 保存任务,记录自定义的任务名称,例如
RunTestPy
- 替换原有Paramiko的执行命令,改为触发该任务计划即可:
import paramiko ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(ip, username=serverUser, password=serverPassword) # 触发预配置的任务计划,脚本将直接在RDP用户的可见会话中启动 stdin, stdout, stderr = ssh.exec_command('schtasks /run /tn "RunTestPy"') print(stdout.read().decode("gbk")) print(stderr.read().decode("gbk")) ssh.close()
注意:使用该方案需要保持RDP对应用户处于登录状态(断开RDP即可,不要执行注销操作),任务触发后脚本会在该用户桌面运行,后续连接RDP可直接看到脚本控制台窗口和实时输出。
方案2:通过PsExec指定会话启动(无需预配置任务)
适合临时执行脚本的场景,需要先把微软官方PsExec工具放到VPS的C:\Windows\System32目录下。
- RDP登录VPS,执行命令
query session,查询当前RDP用户对应的会话ID(通常RDP会话ID为1或2,在返回结果的ID列可查) - 修改Paramiko执行命令,通过PsExec指定交互式会话启动脚本:
import paramiko ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(ip, username=serverUser, password=serverPassword) # 将命令中的2替换为实际查询到的RDP会话ID,脚本路径替换为test.py的绝对路径 # -i 指定在交互式会话运行,-d 表示启动后立即返回不等待进程结束 run_cmd = 'psexec -i 2 -d python C:\\your\\script\\path\\test.py' stdin, stdout, stderr = ssh.exec_command(run_cmd) print(stdout.read().decode("gbk")) print(stderr.read().decode("gbk")) ssh.close()
注意:如果RDP用户已注销,对应会话不存在时该命令会执行失败。
避坑说明
不要尝试直接在exec_command中使用start、cmd /c start类命令启动脚本,这类方式启动的进程依然运行在SSH的隔离会话中,RDP桌面无法观测到运行状态。
内容的提问来源于stack exchange,提问作者Ned Hulton
相关产品推荐
相关产品推荐

