Running remote GUI app in Powershell Running remote GUI app in Powershell powershell powershell

Running remote GUI app in Powershell


Using standard PowerShell methods (WinRM, WMI) you can't launch applications with GUI. The only solution I know about is to use PsExec from SysInternals (or similar tools). It can launch applications which present GUI to the user. Your command line will look like this:

& ".\psexec" -accepteula -i "\\computername" -u "domain\username" -p "password" "command line"
  • -accepteula — silently accept EULA.
  • -i — allow GUI.

Other solutions are more hacky, including remote adding of tasks to the scheduler.


Since I came across this recently, here is my solution using Discord's suggestion of adding a remote task. I preferred the "hack" over having to setup a separate tool.

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    }}