在同一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中的WTSQueryUserToken和CreateProcessAsUser 。
另外一个想法是,为了不在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在另一个答案中提到的。
C:\Windows\PSTools C:\Windows\PSTools添加到您的PATH tasklist将工作,或一个花哨的单行: $session = tasklist /fo CSV | findstr RDP ; $session = $session.Split(",")[3] ; $session.Split('"')[1] ) 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简单地通过任务本身的“名称”进行调用。
要调用任务,请按照您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小时内,将会详细编写这样的代码,我希望能为大家提供基本结构。