Boot Runner Auto VM logoff script for VMware Fusion

Instead of following the instructions that needed me to modify our windows image I wanted to come up with a script that would also shutdown the Host OS after the VM was closed.

I came up with this way specifically for VMWare fusion utilizing the vmrun list command and it seems to work pretty well so I thought I would share and get any input on it. I am calling this script from a Launch Agent that simply runs it on login for my vmuser.

It starts the VM and then waits to detect if the VM is running then does a loop while the VM is on. As soon as the VM no longer exists it shuts down the Host OS.

#!/bin/bash

###################################################################

#Script Name	:VMware Fusion Auto Shutdown                                                                           
#Description	:This script runs with a local user called vmuser that runs a vmware fusion virtual machine.
#				:It launches the VM and then waits for the VM to shutdown, when it does it reboots the Host OS.
#				:This makes for a seamless VM experience for the end users.
#				:This script should be called by the launch agent listed bellow. 
#				:
#Run as user    :vmuser
#Runs at        :/vmuser/LogonScipts/
#LaunchAgent 	:/vmuser/Library/LaunchAgents/com.uva.vmshutdown.plist


###################################################################

#Script Name for Logging
scriptname="VMshutdown"
#Date and time format for logging
date=`date +%d/%m/%Y_%H:%M:%S`


###################################################################

#Functions (Blocks of Code that will be Called later in the Script Section)

function startvm {
	#Start VM if not already started
	vmcount=$(/Applications/VMware\ Fusion.app/Contents/Library/vmrun list | grep -m1 "" | awk '{print $4}')
	if [ "$vmcount" = "0" ];
	then
	echo "Starting VMWare VM"
	/Applications/VMware\ Fusion.app/Contents/Library/vmrun start /VM/Windows\ 10\ x64.vmwarevm
	echo "Waiting for for VM startup"
	sleep 5
	vmcount=$(/Applications/VMware\ Fusion.app/Contents/Library/vmrun list | grep -m1 "" | awk '{print $4}')
	else
	echo "VM Already Started"
	fi
} 

function waitforshutdown {
	#If VM exists wait for it to Shutdown
	if [ "$vmcount" = "1" ];
	then
		vmcount=$(/Applications/VMware\ Fusion.app/Contents/Library/vmrun list | grep -m1 "" | awk '{print $4}')
		while [ "$vmcount" = "1" ]
		do
			vmcount=$(/Applications/VMware\ Fusion.app/Contents/Library/vmrun list | grep -m1 "" | awk '{print $4}')
			if [ "$vmcount" = "1" ];
			then	
			sleep 2
			echo "Waiting for VM to Shutdown"
			#Simulate user input stops Host OS from sleeping while VM is running
			caffeinate -u -t 1
			else
			#Once VM is Shutdown restart Host OS
			echo "VM has shutdown"
			osascript -e 'tell app "System Events" to restart'
			fi
		done
	else
		#Shutdown host OS in 10 seconds if no VMs are runing. 
		vmcount=$(/Applications/VMware\ Fusion.app/Contents/Library/vmrun list | grep -m1 "" | awk '{print $4}')
		if [ "$vmcount" = "0" ];
		then
		#If VM Fails to start restart Host OS
		echo "VM has failed to start"
		echo "Shuting down Host OS in 10 seconds"
		sleep 10
		osascript -e 'tell app "System Events" to restart'
		fi
		echo "No Virtual Machines Installed"
	fi
}

###################################################################
#Script Header (Prints Script name and start date and time for logging.) 
echo "Starting $scriptname on $date"


#Script Start (Place code between the lines bellow) 
#___________________________________________________________________

startvm

waitforshutdown

#___________________________________________________________________
#Script End 

###################################################################
#Script Footer (Prints Script name and end date and time for logging.)
echo "$scriptname Run Complete $date"
exit 0
1 Like

Awesome. Thanks for sharing.

tim