目标服务器采用openssh-server提供连接,接入后启动powershell方式,参考:
【Windows】【DevOps】Windows Server 2022 在线/离线 安装openssh实现ssh远程登陆powershell、scp文件拷贝-CSDN博客
启动一个图形界面程序notepad++
本地运行
远程桌面到目标服务器,在powershell下执行
Start-Process "C:\Program Files\Notepad++\notepad++.exe" -WindowStyle Normal -PassThru
命令行回显

此时远程桌面可以看到弹出了notepad++图形界面窗口

远程powershell运行(无图形界面)
从远程ssh登陆到这台服务器,启动powershell,执行同样的指令
Start-Process "C:\Program Files\Notepad++\notepad++.exe" -WindowStyle Normal -PassThru

此时可以观察到,并没有在远程桌面环境启动notepad++的图形界面窗口,之前本地启动的notepad++也没有置顶。
两个进程分析
Get-Process | findstr /i Note

可以看到,本地和远程分别启动了一个独立的notepad++进程
本地再次启动观察

可以发现,同一个桌面会话中,notepad++发现已经有一个程序会主动退出新的进程,并且让之前的窗口置顶。
转到任务管理器,详细信息,可以看到两个powershell及notepad++会话ID分别是0,5。
同时注意到ssh登陆账号yeqiang的会话ID是0。

远程powershell会话信息

本地powershell会话信息

初步推测两个进程类似于登陆了两个独立的远程桌面,远程的powershell启动的notepad++即使开启了图形界面(不确定,目前没看到报错),本地会话(sessionid=5)也看不到。似乎没有切换会话id的方法。
采用tscon 0无权限
PS C:\Windows\system32> tscon 0
无法将 sessionID 0 连接到该会话,错误代码 5
错误[5]:拒绝访问。
PS C:\Windows\system32> query user
用户名 会话名 ID 状态 空闲时间 登录时间
>yeqiang rdp-tcp#0 5 运行中 . 2024/10/12 8:53
使用stop-process pid方式关闭进程。
启动一个命令行程序
编写一个简单的C#控制台程序
static void Main(string[] args)
{
while (true)
{
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"));
Thread.Sleep(1000);
}
}
放到服务器C:\Users\yeqiang\ConsoleApp1.exe
本地运行
# 日志文件路径
$logFilePath = "C:\Users\yeqiang\ConsoleApp1.exe.log"
# 应用程序路径
$appPath = "C:\Users\yeqiang\ConsoleApp1.exe"
# 启动应用程序,并将输出重定向到日志文件
Start-Process -FilePath $appPath -RedirectStandardOutput $logFilePath".stdout" -RedirectStandardError $logFilePath".stderr" -PassThru
由于重定向了输出,因此控制台的内容就输出到了日志文件,控制台本身就没有输出了。(符合后台服务程序 的效果)
注意,此方案日志文件每次启动都会被覆盖!

远程powershell运行
Start-Process(后台运行失败)
同样的指令
# 日志文件路径
$logFilePath = "C:\Users\yeqiang\ConsoleApp1.exe.log"
# 应用程序路径
$appPath = "C:\Users\yeqiang\ConsoleApp1.exe"
# 启动应用程序,并将输出重定向到日志文件
Start-Process -FilePath $appPath -RedirectStandardOutput $logFilePath".stdout" -RedirectStandardError $logFilePath".stderr" -PassThru

日志正常写入,说明程序正常运行,只是无界面!

此时推出远程powershell,发现:程序退出!

Start-Job(后台运行失败)
# 日志文件路径
$logFilePath = "C:\Users\yeqiang\ConsoleApp1.exe.log"
# 应用程序路径
$appPath = "C:\Users\yeqiang\ConsoleApp1.exe"
# 判断日志文件是否存在,如果不存在则创建
if (-not (Test-Path $logFilePath)) {
New-Item -ItemType File -Path $logFilePath -Force
}
# 启动应用程序,并将输出和错误追加到日志文件
Start-Job -ScriptBlock {
param($appPath, $logFilePath)
& $appPath 2>&1 | Tee-Object -FilePath $logFilePath -Append
} -ArgumentList $appPath, $logFilePath
同样退出会话连接,任务也终端了!
Get-Job分析发现,远程会话有数据,本地powershell无数据,这个job是跟会话关联的,不是跟用户或者操作系统关联(与linux的crontab概念不同)
远程

本地


518

被折叠的 条评论
为什么被折叠?



