Start a Program on the Remote Active Desktop with PowerShell
The goal is to run a command to open a program window like Notepad or Photoshop on a remote computer desktop using PowerShell Remoting. This powerful feature allows us to establish remote sessions, but by default, it only allows executing scripts on the target machine as services. So, the established session is disconnected and not visible to the user watching the remote computer screen. The graphic interfaces of programs started in the session are not visible either. However, we are set in this tutorial to show how to leverage the Task Scheduler to open an application window on a remote desktop and make it visible to the user's eyes.
1. The context
In this section, we are opening a program from a PowerShell session, for instance, Notepad. We describe why it is not visible on the remote desktop by default.
The commands below open an interactive session with the remote computer identified on the network as inonw-svr
. You will notice the chevron arrow pointing to the properties of the current session, for instance, the services
session. Under the STATE
header, we see Disc
for Disconnected.
PS> $Session = New-PSSession -ComputerName 'inonw-svr' -Credential (Get-Credential)
PS> Enter-PSSession -Session $Session
[inonw-svr]: PS> query.exe session
SESSIONNAME USERNAME ID STATE TYPE DEVICE >services 0 Disc console Administrator 1 Active
We start the Notepad application from the services
session.
[inonw-svr]: PS> Start-Process notepad.exe
Notepad is open as a background process. The desktop does not display the usual signs that a particular GUI application is open: no icon on the taskbar or the system tray.
The red arrows in the image above show the taskbar and the system tray. The green arrow shows that Notepad is running as a service.
[inonw-svr]: PS> tasklist.exe /fi 'imagename eq notepad.exe'
Image Name PID Session Name Session# Mem Usage ========================= ======== ================ =========== ============ notepad.exe 7100 Services 0 10,540 K
What the Task Manager shows.
2. Using Task Scheduler
The Task Scheduler utility is built into Windows and allows us to schedule executions of programs. A scheduled task is set to Run only when the user is logged on by default. This property specifies that the defined action executes in the active or connected session with which the user can interact. We can thus use this utility to achieve our goal.
PowerShell provides a set of cmdlets to help us manage scheduled tasks without opening the Task Scheduler window. We can obtain the list of them by running the below command. I narrowed the list down to the cmdlets used to open the Notepad window in this tutorial.
[inonw-svr]: PS> Get-Command -Noun ScheduledTask* | Select-Object Name
Name ---- New-ScheduledTaskAction Register-ScheduledTask Start-ScheduledTask Unregister-ScheduledTask
We now run commands to open Notepad using the Task Scheduler.
We will open a file whose name is Message.txt
that contains the text "Hello World!
" and it is located in the current directory.
[inonw-svr]: PS> $FileName = "$PWD\Message.txt"
[inonw-svr]: PS> 'Hello World!' | Out-File $FileName
We create the RemoteExec
scheduled task that will be used to open Notepad. The above image of the Task Scheduler shows it after creation.
[inonw-svr]: PS> $TaskAction = New-ScheduledTaskAction -Execute notepad.exe -Argument $FileName
[inonw-svr]: PS> $Task = Register-ScheduledTask -TaskName RemoteExec -Action $TaskAction
Note that this task has no trigger. It is not an issue since we start the task ourselves. This time the application window opens on the active desktop as the image below shows.
[inonw-svr]: PS> Start-ScheduledTask -InputObject $Task
We run the Tasklist.exe utility and see that Notepad is open in the Console
session which is in the Active
state.
[inonw-svr]: PS> tasklist.exe /fi 'imagename eq notepad.exe'
Image Name PID Session Name Session# Mem Usage ========================= ======== ================ =========== ============ notepad.exe 220 Console 1 5,480 K
Our task is complete. Let us now unregister the task; leave and remove the Services
session.
[inonw-svr]: PS> Unregister-ScheduledTask -InputObject $Task -Confirm:$false
[inonw-svr]: PS> Exit-PSSession
PS> Remove-PSSession $Session
3. The Send-NotepadMessage Script
The Send-NotepadMessage script is a tiny project I developed based on the solution described in this tutorial. I wrapped it in a simple Windows form, as the below image shows.
Below is the solution written as a function that is called when the Send button is clicked. The command Invoke-Command
is used in place of the PSSession
cmdlets of the previous sections. They are not required since we are not opening interactive sessions.
using namespace System.Management.Automation
function Send-NotepadMessage {
[CmdletBinding()]
param(
[ValidateNotNullOrWhiteSpace()]
[string] $ComputerName,
[ValidateNotNull()]
[Credential()]
[PSCredential] $Credential = [PSCredential]::Empty
[string] $Message,
)
$SenderFilename = ".\Message from $Env:USERNAME.txt"
Invoke-Command -Scriptblock {
$Using:Message | Out-File $Using:SenderFilename
$TaskAction = New-ScheduledTaskAction -Execute notepad.exe -Argument $Using:SenderFilename -WorkingDirectory $PWD
$Task = Register-ScheduledTask -TaskName RemoteExec -Action $TaskAction -Force
Start-ScheduledTask -InputObject $Task
Unregister-ScheduledTask -InputObject $Task -Confirm:$false
Remove-Item $Using:SenderFilename -Force
} -ComputerName $ComputerName -Credential $Credential
}
The demo of the project.
Comments
Post a Comment