如何在PowerShell的Enter-PSSession中指定远程主机活动会话ID?
解决:通过PowerShell指定活动会话ID运行远程GUI程序
问题背景
要在远程Windows主机上运行带GUI的程序,原本用PSExec.exe可以指定活动会话ID实现可视化运行,但PSExec需要明文写入密码,安全性不足。改用更安全的PowerShell远程会话(Enter-PSSession)时,无法直接指定会话ID,需解决此问题。
实现步骤
1. 远程获取活动会话ID
先通过PowerShell安全获取目标主机的活动会话ID,替代query session命令:
$remoteHost = "目标主机名或IP" $cred = Get-Credential # 弹出凭据输入框,避免明文密码 # 远程查询并提取活动会话ID $activeSession = Invoke-Command -ComputerName $remoteHost -Credential $cred -ScriptBlock { quser | Where-Object { $_ -match "Active" } | ForEach-Object { ($_ -split '\s+' | Where-Object { $_ })[2] } }
2. 在指定会话中启动GUI程序
Enter-PSSession本身不支持直接绑定活动会话,需结合远程执行命令,将GUI进程创建在目标会话ID下:
方式一:非交互式远程执行
# 指定要运行的GUI程序路径 $programPath = "C:\Windows\notepad.exe" Invoke-Command -ComputerName $remoteHost -Credential $cred -ScriptBlock { param($sessionId, $path) # 通过Win32_Process创建指定会话的进程 New-CimInstance -ClassName Win32_Process -Namespace root/cimv2 ` -Property @{ CommandLine = $path; SessionId = $sessionId } ` -MethodName Create } -ArgumentList $activeSession, $programPath
方式二:交互式会话内执行
如果需要先进入Enter-PSSession交互式会话,再运行GUI程序:
# 进入远程交互式会话 Enter-PSSession -ComputerName $remoteHost -Credential $cred # 会话内获取活动会话ID $activeSession = quser | Where-Object { $_ -match "Active" } | ForEach-Object { ($_ -split '\s+' | Where-Object { $_ })[2] } # 启动GUI程序到指定会话 New-CimInstance -ClassName Win32_Process -Namespace root/cimv2 ` -Property @{ CommandLine = "C:\Windows\notepad.exe"; SessionId = $activeSession } ` -MethodName Create
核心说明
- Enter-PSSession建立的是PowerShell远程管理会话,默认运行在后台会话(如会话0),无法直接关联用户的交互式桌面会话,因此需手动指定会话ID创建进程。
- 用
Win32_Process的Create方法指定SessionId,能确保GUI进程在用户的活动会话中启动,实现可视化运行。 - 全程使用
Get-Credential输入凭据,避免明文密码,安全性优于PSExec。
内容的提问来源于stack exchange,提问作者Edwin
相关产品推荐
相关产品推荐

