VMware Fusion Tips and Tricks

Overview

This writeup came about as I was trying to figure out better ways to manage my at home lab environment. I have an old laptop I use as a VMware Fusion host and run a handful of VM's in it - Domain Controller, Web Applicaiton Proxy, ADFS, Cert Authority, etc.. One of my goals was to allow my laptop to utilize its own power management capabities to sleep durring after hours - and wake automatically in the morning so my VM's would be ready and wating for me as I finish up my morning cup of coffee. I was stuggeling with how to get them boot up and shut down at predefined times - cleanly - after doing a bit of reasearch i came across the vmrun command. This lets you manage your VM's in fusoin via the command line! With that in mind - i was able to write up a quick script to power them up in the morning and down again in the evening. Once I had that in had, i whipped up a quick Launchd agent, and macOS handles the rest for me.

VMware Fusion command line tool

As I mentioned in the overview, I had been toying this idea over in my head, use applescript, automator, etc.. to accomplish the start up / shut down operations on a scheduled basis. After some dutiful Google reasearch I came across a forum post mentioning a command line tool to view running Virtual Machines, and was curious as to whatelse the command supported.

To start off - lets jump to Terminal app and run the vmrun command with no arguments

vmrun

With just that simple command we can see there are a handful of arguments we can use with the vmrun command

and surprise! There is a pair of arguments, start and stop that look like will do exactly what I want. The one quirk I have seen with this vmrun command is how you address which vm to act against. Rather than just addressing it as a short friendly name you have to specifiy the path to the VM file.

So for me, i want to manage the power state of a VM called Windows 10 x64, a working start command looks like this:

vmrun -T fusion start /Users/davidpacold/Virtual\ Machines.localized/Windows\ 10\ x64.vmwarevm

conversely a working shutdown command looks like:

vmrun -T fusion stop /Users/davidpacold/Virtual\ Machines.localized/Windows\ 10\ x64.vmwarevm

That is the vmrun command, the-T argument specifies if this is going to be run against fusion or workstation, and then the action - start / stop - and finally the path to my vm file.

So now that I have my working comamnds to start and stop my vms, I want to do this on a scheduled basis.

Exploration into LaunchD

The first thing I am going to do is build a script to start up and shutdown my virtual machines, esstentially just a repeating list of commands above but for each vm. Pretty straightforward stuff here - here is my example script. After the first VM boots, I have a sleep of 150, which is about a 2 minute 30 second wait before it kicks off the next one.

#!/bin/sh

# this script starts my 2 Virtual Machines daily

vmrun -T fusion start /Users/davidpacold/Virtual\ Machines.localized/Windows\ 10\ x64.vmwarevm

sleep 150

vmrun -T fusion start /Users/davidpacold/Virtual\ Machines.localized/Windows\ 10\ x64-2.vmwarevm

  • Save this file, I called mine vmstart.sh

  • Now we want to make the file executable - head back to the Terminal

  • run the command:

chmod 755 vmstart.sh

The next step we are going to do is create a new plist file that will configure our LaunchD service. There are a number of ways to configure our jobs - a great resource i would encourage you to take a look at is: https://launchd.info for all the details on the service and configuration options.

For me, I am going to a pair of files in the ~/Library/LaunchAgents/ folder

touch ~/Library/LaunchAgents/com.davidpacold.vm.start.plist

Lets edit the file and add our configuration, my plist file looks like this. My configuration based on the calendar interval settings runs my vm start script daily @ 7 am


<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

<plist version="1.0">

<dict>


<key>Label</key>

<string>com.davidpacold.vm.start</string>


<key>StartCalendarInterval</key>

<dict>

<key>Hour</key>

<integer>7</integer>

<key>Minute</key>

<integer>0</integer>

</dict>


<key>StandardErrorPath</key>

<string>/Users/davidpacold/documents/script/err.log</string>


<key>StandardOutPath</key>

<string>/Users/davidpacold/documents/script/out.log</string>


<key>ProgramArguments</key>

<array>

<string>/Users/davidpacold/documents/startvm.bashrc</string>

</array>


</dict>

</plist>


Now Save the file

  • Now we will load the plist into the LaunchD service so that it executes on our requested schedule

Launchctl load ~/Library/LaunchAgents/com.davidpacold.start.vm.plist

  • To verify our plist was loaded successfully, run the command:

launchctl list | grep com.davidpacold