在Powershell中运行远程GUI应用程序

Ste*_*ark 17 powershell powershell-remoting

我们有一个自定义组件,它包含了PowerShell的一些功能,因此可以在BizTalk 2006中使用它.对于大多数操作(检查文件路径,复制或移动文件),这样可以正常工作.但是,我们需要远程启动GUI应用程序以进行一些处理.组件本身处理与远程盒的连接,我们所要做的就是设置一些参数然后告诉它执行一个命令

Start-Process -FilePath "path to exe" -ArgumentList "arguments for exe" -WorkingDirectory "workingdir for exe"
Run Code Online (Sandbox Code Playgroud)

问题是:如果我们从盒子本身的powershell命令行运行它,这很好.然而,当我们远程启动它时(从BizTalk,从测试工具,甚至使用远程Powershell命令行和通过Start-PSSession连接),此应用程序将短暂运行然后退出而不实际执行任何操作.我怀疑是因为有问题的exe需要加载GUI才能运行该进程,这就是导致问题的原因.我已经尝试了我能想到的一切,包括-NoNewWindow和-WindowStyle,但无济于事.任何帮助实现这项工作将非常感激.

注意:我们无法访问我们尝试运行的应用程序的源代码,因为它是较旧的win32应用程序,并且未提供此应用程序的批处理或命令行版本.

Ath*_*ari 18

使用标准PowerShell方法(WinRM,WMI)无法使用GUI启动应用程序.我所知道的唯一解决方案是使用SysInternals(或类似工具)中的PsExec.它可以启动向用户呈现GUI的应用程序.您的命令行将如下所示:

& ".\psexec" -accepteula -i "\\computername" -u "domain\username" -p "password" "command line"
Run Code Online (Sandbox Code Playgroud)
  • -accepteula - 默默接受EULA.
  • -i - 允许GUI.

其他解决方案更加苛刻,包括向调度程序远程添加任务.

  • 注意,-i参数有时需要用户会话ID,可以先通过"quser/SERVER:computername"命令获取. (3认同)

Ben*_*Ben 8

自从我最近遇到这个问题以来,这是我使用Discord建议添加远程任务的解决方案.我更喜欢"黑客"而不必设置一个单独的工具.

function Start-Process-Active
{
    param
    (
        [System.Management.Automation.Runspaces.PSSession]$Session,
        [string]$Executable,
        [string]$Argument,
        [string]$WorkingDirectory,
        [string]$UserID,
        [switch]$Verbose = $false

    )

    if (($Session -eq $null) -or ($Session.Availability -ne [System.Management.Automation.Runspaces.RunspaceAvailability]::Available))
    {
        $Session.Availability
        throw [System.Exception] "Session is not availabile"
    }

    Invoke-Command -Session $Session -ArgumentList $Executable,$Argument,$WorkingDirectory,$UserID -ScriptBlock {
        param($Executable, $Argument, $WorkingDirectory, $UserID)
        $action = New-ScheduledTaskAction -Execute $Executable -Argument $Argument -WorkingDirectory $WorkingDirectory
        $principal = New-ScheduledTaskPrincipal -userid $UserID
        $task = New-ScheduledTask -Action $action -Principal $principal
        $taskname = "_StartProcessActiveTask"
        try 
        {
            $registeredTask = Get-ScheduledTask $taskname -ErrorAction SilentlyContinue
        } 
        catch 
        {
            $registeredTask = $null
        }
        if ($registeredTask)
        {
            Unregister-ScheduledTask -InputObject $registeredTask -Confirm:$false
        }
        $registeredTask = Register-ScheduledTask $taskname -InputObject $task

        Start-ScheduledTask -InputObject $registeredTask

        Unregister-ScheduledTask -InputObject $registeredTask -Confirm:$false
    }

}
Run Code Online (Sandbox Code Playgroud)