使用Powershell在远程机器上启动GUI程序

在同一networking上安装了两台Windows 7机器。
我启用了所需的一切,以便他们可以与winrm沟通。

当我运行以下命令:

Invoke-Command -ComputerName REMOTE-PC -ScriptBlock { Start-Process calc.exe }

它工作正常,但在远程机器上永远不会看到该程序。 据我所知,这是预期的行为。

我假设stream程正确启动,然后在会话结束时立即closures。 如何运行程序以使其显示在主机上?

通过devise,你并不是真的能够在其他人的会话中启动进程。

(要说明的是,即使您在计算机桌面上以交互方式login,并且使用相同的凭据同时还有另一个单独的networkinglogin到同一台计算机,这些仍然被视为两个不同的login会话。

这仅仅是针对Windows本身的安全模式,而试图颠覆它的尝试将会被压垮。 所以你不可能find一个简单,可支持的方式来做到这一点。 这在技术上是可行的,但它涉及以本地系统的身份运行,复制另一个login用户的安全令牌,并使用该备用令牌启动一个进程。 您将需要Windows API,这几乎是Powershell不太擅长的。 有关更多详细信息,请参阅Windows API中的WTSQueryUserTokenCreateProcessAsUser

另外一个想法是,为了不在Cheerios中完全撒尿,可以通过远程创build启动stream程的计划任务来完成此任务。 有关更多信息,请参阅http://blogs.technet.com/b/heyscriptingguy/archive/2005/09/06/how-can-i-remotely-start-an-interactive-process.aspx

编辑:哦,我忘了…很确定PsExec与-i参数可以做到这一点。 您必须提供login会话ID。 并有权限做到这一点。 它最有可能使用我提到的相同的Windows API,它利用了PsExec安装作为本地系统运行的临时服务的事实。

我能够得到这个工作使用PsExec在另一个答案中提到的。

  1. 下载PSTools
  2. 解压到C:\Windows\PSTools
  3. C:\Windows\PSTools添加到您的PATH
  4. 获取RDP会话的进程ID( tasklist将工作,或一个花哨的单行: $session = tasklist /fo CSV | findstr RDP ; $session = $session.Split(",")[3] ; $session.Split('"')[1]
  5. 启动过程: PsExec.exe -s -i 123 calc.exe (“123”是RDP会话ID)

这是我用Ansible 2.3.0来做的:

 - name: get RDP session number win_shell: "{{ item }}" with_items: - $session = tasklist /fo CSV | findstr RDP ; $session = $session.Split(",")[3] ; $session.Split('"')[1] register: rdp_session - name: start calc.exe win_shell: PsExec.exe -s -i {{ rdp_session.results[0].stdout_lines[0] }} calc.exe 

您可以在远程计算机上创build一个“可调用钩子”:这是一个计划任务,设置为“仅在用户login时运行”,指定为在执行后将login的用户帐户下运行。 任务的动作是要运行的可执行文件。

计划任务可以通过powershell或schtasks远程创build,随后使用schtasks或PowerShell的Start-ScheduledTask简单地通过任务本身的“名称”进行调用。

  1. 在远程计算机上,创build由正在运行当前会话的用户运行的准系统计划任务。
  2. 将任务设置为仅在用户login时运行“
  3. 如果计划任务的“操作”选项卡中的.exe或项目具有在文件系统项目上设置的“以pipe理员身份运行”(右键单击属性,兼容性>以pipe理员身份运行),则计划任务需要在提升特权,否则将失败或不显示。
  4. 计划任务的作者应具有pipe理员权限,以便在远程调用时,可以使用此pipe理员帐户调用计划任务,然后在“仅在用户login时运行”下指定的用户configuration文件中执行该计划任务。
  5. 确保机器以该用户身份login。
  6. 如果在机器被locking的情况下这个任务能够正确执行,那么它可能取决于应用程序。 根据我的经验,
  7. 从这里,您可以使用schtasks.exe并调用计划任务的名称以及主机名,并传递用于创build计划任务(而不是将要login的用户)的提升帐户的凭据。
  8. 如果远程机器正在运行一个支持Start-ScheduledTask的powershell版本,你可以在powershell中调用它。

要调用任务,请按照您input的名称引用任务:

 schtasks /run /TN "mytaskname" /s "host" /u "user" /p "password" 

使用powershell中的schtasks.exe或New-ScheduledTaskPrincipal可以远程创build计划任务。 如果任务中的可执行文件或“操作”项在文件系统上标记为“以pipe理员身份运行”,则该任务将需要在创build任务期间附加New-ScheduledTaskPrincipal凭证,以便适当地设置该属性。

当前login的用户可以是一个移动目标,尽pipe可以在计划任务创build之前通过PowerShell通过Get-LoggedOnUser查询。

在接下来的48小时内,将会详细编写这样的代码,我希望能为大家提供基本结构。