Periodically my work tasks involve running the VMWare vSphere Client (it even still exists in ESXi 6), which is a "thick" Microsoft Windows (C#) executable. Because my desktop environment is OS X the easiest way to deal with this is to log into a Microsoft Windows VM and run it from there. (Much of the recent functionality is in the VMWare vSphere Web Client, some new features only in the Web Client, but the VMWare vSphere Web Client requires Adobe Flash, which I also do not install into my default desktop -- for security reasons. So the vSphere Windows client is at least as convenient to me as the Web Client.)

Up until today, running the vSphere client from my OS X Desktop was a multi-step process that went something like:

  1. Start Terminal

  2. Use Terminal to run rdesktop to connect to Windows VM, with a bunch of parameters

  3. Log into Windows VM

  4. Wait for Windows Desktop to appear

  5. On Windows VM launch the VMWare vSphere Client

  6. Confirm Login into VMWare vSphere Client

  7. Wait for vSphere interface to populate

  8. Try to remember what I wanted to do in the first place

  9. Do original task

  10. Exit vSphere Client

  11. Log out of Windows VM

Very early on I automated the rdesktop command line, into a shell script, which made the remaining steps simple -- but time consuming.

Today, while looking for something else, I found rdesktop supports -s to specify a shell to launch when logging in via RDP, which "starts a specific application instead of Explorer". That sounded ideal to save a couple of steps.

It took some research to find out how to use that feature -- you cannot just specify a full path of something to run (unlike, eg, running commands via ssh). Instead you (or your Microsoft Windows Administrator) need to configure a "Remote App" on the Microsoft Windows VM that can be launched directly, and then have rdesktop trigger that.

To configure a RDP Remote App go to "Administrative Tools" -> "Remote Desktop Services" -> "RemoteApp Manager" on the Windows VM. Once that loads (it takes a while to initialise!), in the bottom left "RemoteApp Programs" pane, right click and choose "Add RemoteApp Programs". In the Wizard that comes up, find the "VMWare vSphere Client" option, highlight that, then choose "Properties". You want to configure:

  • Alias: VpxClient

  • Always use the following command-line arguments:

    -passthroughAuth -s FQDN_OF_VCENTER
    

    where FQDN_OF_VCENTER is the hostname of your vCenter server.

then check that Application so it is added to the application list. After it is added, double check your intended arguments made it into the list ready for automatic connection to your VMWare vCenter: those arguments (a) use Windows Domain Authentication to vCenter (which you typically want), and (b) auto-specify the vCenter so you do not have to confirm that when launching.

Once added, select the VpxClient item in the list, and choose the "Create .rdp File" link above it to create a RDP file that gives you the parameters to use; that .rdp can then be copied to Windows clients and run directly by double clicking it. For use on OS X what you want to do is look at the resulting file (by default) in C:\Program Files\Packaged Programs, and find the alternate shell::s: setting -- which should be somethig like ||VpxClient. it is plain text so type FILE will how useful output, and alternate shell::s: is near the end of the output. The contents of that alternate shell::s: entry is what can be used with the -s option in rdesktop.

At this point, test that it works by running:

rdesktop .... -s "||VpxClient" WINDOWS_VM

and all going well once you authenticate to the Windows VM, the VMWare vSphere Client will run automatically, automatically log you in with Windows Domain Authentication, and then you can interact with the client directly. Plus when you exit the vSphere Client you will be automatically logged out of Windows. Saving a bunch of manual steps.

Having done that, I then wanted to be able to run it from my desktop without even having to open a new Terminal window -- since I have been spending lots of time opening Terminal windows just to use them to launch one thng, that did not need a terminal, and then closing the Terminal window again.

The canonical solution to this problem is to use a "launcher" which will take keyboard input, of which there are three main contenders:

  1. LaunchBar (30 day demo, then EUR 24)

  2. QuickSilver (Donationware)

  3. Alfred (Basic features free, advanced features need a EUR 17 Powerpack)

After reading a few reviews, I decided to try Alfred first as I had previously tried QuickSilver years ago and found it did not work quite the way I had in mind, at least by default. Here my ideal use case is:

  1. Cmd-Space (replacing Spotlight, which I hardly use)

  2. Type in name of shell script I already had

  3. Hit enter, and it runs

Alfred is installed by unzipping the zip file of the download, putting that somewhere under /Applications, and then running it for the first time -- at which point it will default to adding itself to the "run at login" list ("Apple" -> "System Preferences" -> "Users and Groups" -> your user -> "Login Items"). (To my surprise there is no "disk image" driven installer.)

To have Alfred run with CMD-Space you need to:

  1. Change the keyboard shortcuts that already use CMD-Space to something else

  2. Highlight the "Alfred Preferences" -> General -> "Alfred Hotkey" option and press Cmd-Space to save that.

It turns out that there are two default keyboard shortcuts that conflict:

  1. Spotlight

  2. Input Sources

to change those, go to "Apple" -> "System Preferences" -> "Keyboard" -> "Shortcuts", and then find the "Spotlight" and "Input Sources" sections. For each conflicting shortcut, click on the keys of the shortcut, then hold down a new shortcut combination. I chose to add Option to the Spotlight ones (eg, Option-Cmd-Space), and Control to the Input Sources ones (eg, Ctrl-Cmd-Space). After I had done that, I could change Alfred's keyboard shortcut to Cmd-Space.

Actually getting Alfred to recognise the name of the shell script that I already had proved more illusive -- at least with the basic free version it appeared to ignore shell scripts, even when I added the directory containing them into the search list and tried dragging'n'dropping one of them onto its "Advanced..." file types.

The canonical solutions seem to be either using an Alfred Workflow per script (a "Powerpack feature") or using the Terminal Feature (also a "Powerpack feature"); see also running shell commands without opening a Terminal.

The next best alternative, which works with the base version of Alfred, appears to be to use Automator to create an .app that runs the shell script, and then put that .app somewhere that Alfred will look. I chose /Applications/Wrappers, and added that to Alfred's search path in the "Features" page of the Alfred Preferences (because Alfred seemed to ignore (hidden?) directories under my home directory).

To create a "wrapper" Application in Automator:

  1. Start Automator (eg, open /Applications/Automator, or use Alfred :-) )

  2. Choose to create an "Application"

  3. From the Actions Library drag "Run a Shell Script" into the working pane on the right

  4. For the "shell script" enter the path to the shell script you already have written, eg ~/.bin/vsphere (because it is bash you can use "~" to expand to your home directory)

  5. Then do File -> Save to save that Application out

Try running the resulting application by double clicking on it, and make sure it results in starting resktop, connecting to the server, etc. If you have problems check:

  • The shell script explicitly sets the PATH, as the PATH given via Automator is different from the one you might have an an interactive Terminal -- so your shell script may be unable to find commands that it needs

  • The shell script ends with exit 0 on any non-error path, otherwise Automator errors may be displayed on exit.

Assuming the Automator created App works interactively (eg, double clicking), then move it to /Applications/Wrappers (or the directory you chose to tell Alfred about).

Finally you should be able to do:

  1. Cmd-Space (to activate Alfred)

  2. vsphere (or the name you gave the Application)

  3. Enter

and it should run rdesktop, connect to the Windows VM, and once you authenticate, should run the VMWare vSphere Client. Then when you exit the VMWare vSphere Client, it all goes away again. That is about as seamless as it gets.

Best of all, Alfred does command completion, so you probably only have to type a few of those characters before you hit enter. This is much more convenient than the manual steps I was doing before.

As an alternative if you would rather just double click on an icon, you can change the icon of the Automator created App to one that you will recognise later, and then just drag it onto the OS X Dock. (Beware those icon overrides are in the Resource fork so will not always copy easily with the App; you might need to replace it if you move the App around, eg between machines.)

Finally for completeness: I did consider using AppleScript (documentation; third party AppleScript enthusiast site). But the command line tools (osascript, osacompile) do not seem to have a way to produce an Application bundle (only a .scpt file, to be run as osascript FILE.scpt), so it did not directly solve the problem. (The AppleScript Editor GUI has an option to Export an Application, which should work -- but at that point it is no more or less convenient than using Automator.)

ETA, 2015-10-14: After using these for a while I found that the Alfred "running" cog stayed spinning in the top bar for the entire duration of the VM, which started to annoy me once I noticed. That turned out to be due to the Automator wrapper not exiting until the whole application was done. After some fiddling I found that if I put the shell script portion inside paranthesis, redirected stdin/stdout/stderr to /dev/null and ran it in the background, then I could avoid the problem -- the Automator application exited immediately, and no spinning cog was shown.