Skip to content

Scheduling GUI Apps

stagrlee edited this page Jan 14, 2013 · 7 revisions

Background

The standard way of managing windows apps with Rundeck is to invoke jobs over Windows Remote Management or "WinRM". Lots of rundeck users use WinRM with great success. Issues have come up with the approach on later patch releases of Windows 2008, Vista, 7, and Windows 8 due to Session 0 Isolation as jobs that require GUI interactivity or devices traditionally managed by the graphics system of Windows will fail when starting. This problem is effecting newer style cloud applications that leverage the amazing processing capability of the graphics cards. This Isolation issue will also effect automated jobs using powershell to automate GUI applications through the COM programmatic interface.

Solution Overview

There are several approaches to working around Session 0 Isolation posted in numerous blogs. This solution uses Rundeck installed locally on the Windows machine to manage (start/stop/status) the Windows application suffering from Session 0 isolation. A typical topology would implement a spoke and hub command distribution model where the local Windows Rundeck installation will be a spoke to central (hub) enterprise workflow Rundeck server(s). The hub Rundeck workflows would access the remote Rundeck installs through the Rundeck REST APIs. The Windows machine is configured to automatically login at bootup so that the graphics and GUI subsystem of windows are available to rundeck jobs.

Implementation

At time of writting this, no native windows packaging exists for Rundeck so setup for this solution will take some time. The outline is as follows

  1. Install Powershell if it isn't there already
  2. Install the Java Runtime Environment (JRE)
  3. Install the Rundeck launcher jar
  4. Create a sheduled task to run Rundeck at login
  5. Set machine to auto login
  6. Create a test powershell script
  7. Create Rundeck job to invoke test powershell script
  8. Create firewall rule to open Rundeck's port 4440

Install Powershell

This solution was developed on Windows 8 largely because the scheduling and configuration of Windows 8 is more complex than prior versions of Windows due to the inclusion of the tile based start screen (Metro) user interface. Windows 8 and Windows Server 2012 comes with Powershell 3.0. Older versions of Windows can install Windows Management Framework which will include either Powershell 3.0 or PowerShell 2.0. Either version should work.

Optional Powershell setup

Powershell is not configured to run by default. This solution does not require the system policy to be modified to work, but Powershell is a very nice way to setup machines. If you are on a development machine, this will be useful to have. From the "cmd.exe" prompt, you can start the interactive powershell environment by typing "powershell_ise", then you can type in the following commands...

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine
mkdir $HOME/Documents/WindowsPowerShell

Install the Java Runtime Environment

Java is packaged for Windows and is available at Java.COM. If you are going to be using PowerShell, optionally extend your path to the new JRE directory by creating $(HOME)/Documents/WindowsPowerShell/profile.ps1. profile.ps1 will get run when your PowerShell session starts. PowerShell_ISE has a File->New menu to create files.

# Write-Host "Setting up profile"
$env:Path = "C:\Program Files (x86)\Java\jre7\bin;" + $env:Path
# java -version

Install the Rundeck Launcher jar

Create a $(HOME)/Documents/rundeck directory and downlaod the rundeck launcher jar into the new directory from the Rundeck project download page. You can run this powershell to do the work for you by copying the following script into Powershell_ISE and hitting the green triangle "play" button...

mkdir $HOME/Documents/rundeck
$runfile = "rundeck-launcher-1.4.5.jar"
$url = "http://download.rundeck.org/jar/" + $runfile
$path = $HOME + "/Documents/rundeck/" + $runfile
$(new-object System.Net.WebClient).DownloadFile( $url, $path )

Create a test rundeck powershell startup script by doing File->New $HOME/Documents/rundeck/rundeck.ps1

Get-ExecutionPolicy
java -jar $HOME\Documents\rundeck\rundeck-launcher-1.4.5.jar

After you save the file you can hit the green triangle "play" icon to run the script. If you are getting privilege issues check the Get-ExecutionPolicy settings... If all works, you can use a browser to navigate to http://localhost:4440 where Rundeck is running.

Schedule Rundeck to start at login

Microsoft is going away from the "Startup Items" concept of the start menu and going toward using a "Schedule Tasks" management utility. There is an excellent article on Windows 8 and Schedule Tasks at Tech Republic which was followed to create a rundeck task to run at login. Read and study the article. You can either use the powershell script from the previous section or use old DOS syntax which does not require powershell. You can either create the task manually or import the following task after editing the XML with appropriate directory changes for your system.

<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2013-01-13T09:35:24.2174911</Date>
    <Author>DTOWIN8\Lee</Author>
    <Description>Rundeck workflow automation softare</Description>
  </RegistrationInfo>
  <Triggers>
    <LogonTrigger>
      <Enabled>true</Enabled>
    </LogonTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <UserId>DTOWIN8\Lee</UserId>
      <LogonType>InteractiveToken</LogonType>
      <RunLevel>LeastPrivilege</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>false</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
    <UseUnifiedSchedulingEngine>false</UseUnifiedSchedulingEngine>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>P3D</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>"C:\Program Files (x86)\Java\jre7\bin\java.exe"</Command>
      <Arguments>-jar C:\Users\Lee\Documents\rundeck\rundeck-launcher-1.4.5.jar</Arguments>
    </Exec>
  </Actions>
</Task>

Reboot the system, login, and check to see if Rundeck has booted.

Configure Machine to Auto Login at boot

Follow this blog on configuring your machine to automatically login at boot.

Reboot the system, and check to see if Rundeck has booted at login. It takes a few minutes to get scheduled so you will have to wait a bit.

Create a test PowerShell script

Now we will create a test PowerShell script which can control an application. We'll just start the Internet Explorer and open a few browser tabs to various websites. Use PowerShell_ISE's File->New $HOME/Documents/Windows/PowerShell/ie.ps1 and enter the following commands...

$ie = New-Object -ComObject InternetExplorer.Application
$ie.Navigate2("www.yahoo.com")
$ie.Navigate2("www.amazon.com",0x1000)
$ie.Navigate2("www.facebook.com",0x1000)
$ie.Navigate2("www.cnn.com",0x1000)
$ie.Navigate2("www.etrade.com",0x1000)
$ie.Visible = $true

If you have the ExecutionPolicy opened up, optionally run this script by clicking the green triangle "play" icon in PowerShell_ISE and you should see internet explorer statup and open several web tabs. Close the browser window.

The script is representative of a GUI app which you would like to control. Develop your scripts in powershell and add to rundeck as eneeded.

Create a Rundeck job to start a windows GUI app

Open a browser to http://localhost:4440, and login to rundeck. Test an ad hoc startup of internet explorer through rundeck by putting the following command into "command" form, editing the path to your ie.ps1 script and hitting run.

powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -File C:\Users\Lee\Documents\WindowsPowerShell\ie.ps1

Switch to the desktop view if you are in Windows 8's tile view and you should see internet explorer start and several tabs open up. The invocation of powershell has enough overloads to bypass a default security settings on powershell. If this doesn't work, open up Set-ExecutionPolicy (see above) and run this in PowerShell_ISE.

powershell.exe -File C:\Users\Lee\Documents\WindowsPowerShell\ie.ps1

Check for error messages and post on the Rundeck Internet Relay Chat room or to email.

Navigate to the jobs tab (http://localhost:4440/jobs). Click on "New Job" and use the normal procedure to save a job for later utilization.

Create firewall rule to open Rundeck's port 4440

Rundeck runs on port 4440 by default and you will likely need to open the firewall to allow access to this port. By its nature, rundeck allows "arbitrary execution of commands" which in secure computing is a very bad thing, so you will want to be very careful about allowing both network access to rundeck and create very secure passwords. Go carefully here. Follow Microsoft's recommendation on configuration of firewalls.

If remote access is needed test access from a remote machine to Rundeck on the windows machine.

Workflow

Use the Rundeck REST APIs in workflow scripts to allow your Windows GUI based applications to participate in your enterprise workload automation scripts in rundeck.