Automation

tstrohman

Bit poster
I'm using Parallels on OS X for automated software testing (in this case, build tests on various Linux distributions). For this I need to be able to write a script/application that can open, boot, and stop virtual machines.

I'm sure I can hack together a solution that sends mouse clicks to Parallels windows, but I'd rather have something a little more solid than that.

Two other minor (related) requests:
- I'd like to be able to programmatically tell if a VM is running or stopped.
- Parallels Workstation doesn't seem to notice when I've halted by Fedora Core VMs. I have to manually click the "stop" button. That's not a big problem when I'm using them manually, but it means a program will have trouble knowing when the machines have finished.

Thanks for an excellent product!
 
You can specify a VM to load on the parallels command line, and configure that VM to start automatically when opened. Obviously, you don't want to terminate a Linux VM externally - you should do that in a Linux script or program.

You might look into how your VM is doing shutdown in the Linux power management setup. I have many Linux VMs and some 'stop' Parallels and some don't.

You can tell if a VM is running by looking at your network to see if the machine is there. Pinging would probaby accomplish that. You'ld have to delay before terminating parallels to allow the rest of the Linux shutdown after networking is stopped - generally only a few seconds.
 
Last edited:
Use command line offerings: prlsrvctl & prlctl

I know this is old but i searched for similar answers and couldnt find it so I will add my ideas here in case others are searching.

The parallels desktop has some command line tools with parallels desktop that i use which are very handy "prlsrvctl & prlctl". Much better idea than send keys hacks. see the guide: http://download.parallels.com/deskt...US/Parallels Command Line Reference Guide.pdf

For example below is a shutdown script I run to shutdown all of my windows7 virtual machines and then shutdown osx. It checks for all parallels VMs installed, checks if they are pasued or running, if so un-pauses them before sending a shutdown command. You should be able to add a shutdown command for the non windows vms as well.

#########################################################################################
# Parallels VM Friendly Shutdown #
# By Ben Harper #
# #
# Find all Parallels VMs and shut them down (nicely through calls to VMs OS) #
# Then Issue Mac Shutdown statement #
# Ver 1.1 16/11/2011 cheap and nasty - try and remove the su password from shutdown #
# Ver 1.2 18/11/2011 Fixed to loop all vms, not named vas - anyone can use now #
# Ver 1.3 19/11/2011 Uses call to shutdown by os type, so can add other os's #
#########################################################################################

#!/bin/bash

Win7ShutCmd="cmd.exe /c shutdown.exe -s -t 1 " #this is not win 7 specific
#Need to source and Add other OS shutdown commands here

function GetVMOS()
{
prlctl list -a --info "$1" | while read txtline ;
do
if [[ $txtline == *'OS: '* ]] ; then
echo $txtline
fi
done
}

function ShutDownVm()
{
VMType=$(GetVMOS "$1")
case $VMType in
"OS: win-7")
echo "Shutdown a Win7 VM"
prlctl exec "$VMName" $Win7ShutCmd
;;
*)
echo "Don't Know How To Shutdown a $VMType";;
esac
}


x=`/usr/bin/osascript <<EOT
tell application "Finder"
activate
set myReply to button returned of (display dialog "Shutdown?" )
end tell
EOT`

if [[ $x != "OK" ]]; then
exit
fi

prlctl list -a --no-header --output name | while read line ; do # Pipe Parallels List of VM's to loop
VMName=$line # Get Name of VM
VMState=$(prlctl list --no-header -a -o status "$VMName"); #Better Way - no piping text
echo
echo Found - $VMName, State = $VMState
echo

if [[ $VMState == *paused* ]] # If VM Paused
then
echo $VMName was paused, unpausing it
prlctl resume "$VMName"
echo $VMName, State = $(prlctl list --no-header -a -o status "$VMName");
echo
fi
if [[ $VMState == *running* ]] # If VM Paused
then
echo "Tell $VMName to shutdown"
ShutDownVm "$VMName"
fi
done

/usr/bin/osascript << EOF
tell application "System Events"
#shut down
end tell
EOF
 
Last edited:
Awesome!

Ben - this is a great idea! I don't mean to hijack this thread, but I had a similar question.

I am trying to use prlctl to suspend a VM before a SuperDuper backup and resume it after the backup is completed.

I have two scripts that do these things. The first script says:

#!/bin/sh
sudo -u "my_short_username" prlctl suspend "Windows 7"

and the second one says:

#!/bin/sh
sudo -u "my_short_username" prlctl start "Windows 7"

but I'd like to improve them in the following ways:

1. Add an if statement in the first one to check if the VM is already off or suspended, and if so, do nothing.
2. Add an if statement in the second one to check if the VM Is already running or resuming, and if so, do nothing.
3. Generalize the scripts to not require my user name and to account for any running VMs.

I realize that your script above does a lot of this, but I know it does much more and I can't figure out how to modify it to fit the above needs. Can you help?
 
PauseResume

Hi RujusMacBook ,
Here is a hacked together script from my original one.
It will loop through any virtual machines it finds and if running pause them,
then there is some space for your code and then it will loop through and resume them.
Or you can split the script in two.

Please post your final solution.
Cheers
Ben


#########################################################################################
# Parallels PauseResume #
# By Ben Harper #
# #
# Find all Parallels VMs and pause them, do something then go find and resume them #
# Ver 1.1 29/12/2011 - Hacked together from my shutdown #
# script for some dude on the interporn. #
#########################################################################################

#!/bin/bash

prlctl list -a --no-header --output name | while read line ; do # Pipe Parallels List of VM's to loop
VMName=$line # Get Name of VM
VMState=$(prlctl list --no-header -a -o status "$VMName"); #Better Way - no piping text
echo
echo Found - $VMName, State = $VMState
echo

if [[ $VMState == *running* ]] # If VM Running
then
echo $VMName was running, pausing it
prlctl pause "$VMName"
echo $VMName, State = $(prlctl list --no-header -a -o status "$VMName");
echo
fi
done


echo Do your backup here
echo Do your backup here
echo Do your backup here
echo Do your backup here


prlctl list -a --no-header --output name | while read line ; do # Pipe Parallels List of VM's to loop
VMName=$line # Get Name of VM
VMState=$(prlctl list --no-header -a -o status "$VMName"); #Better Way - no piping text
echo
echo Found - $VMName, State = $VMState
echo

if [[ $VMState == *paused* ]] # If VM Paused
then
echo $VMName was running, pausing it
prlctl resume "$VMName"
echo $VMName, State = $(prlctl list --no-header -a -o status "$VMName");
echo
fi
done
 
Last edited:
Ben,

Thank you for your quick reply. The description is hilarious.

Unfortunately this script does not work for me. Here's what I did to try it:

1. Copied the first part of the script to create a suspend script:

Code:
################################################## #######################################
# Parallels PauseResume	 #
# By Ben Harper #
#	 #
# Find all Parallels VMs and pause them, do something then go find and resume them	#
# Ver 1.1 29/12/2011 - Hacked together from my shutdown #
# script for some dude on the interporn.	 #
################################################## #######################################

#!/bin/bash

prlctl list -a --no-header --output name | while read line ; do # Pipe Parallels List of VM's to loop
VMName=$line	# Get Name of VM	
VMState=$(prlctl list --no-header -a -o status "$VMName"); #Better Way - no piping text
echo	
echo Found - $VMName, State = $VMState
echo

if [[ $VMState == *running* ]]	 # If VM Running
then
echo $VMName was running, pausing it
prlctl pause "$VMName"
echo $VMName, State = $(prlctl list --no-header -a -o status "$VMName");
echo
fi	
done

2. Then I saved that as test.command on my desktop
3. Then I went into terminal and chmod'ed it 755
4. Then I double clicked on it to run it but the VM did not shut down. It didn't do anything in fact. Here was the terminal output:
Found - Windows 7, State = running

Windows 7 was running, pausing it
Pause the VM...
The VM has been successfully paused.

What am I doing wrong? Any ideas?

Thanks again!
 
Shutdown VM's For Backup then Restart Them

Sorry, Big Xmas & NewYears so took me a while to recover and remember to write back.

Your not doing anything wrong, I misunderstood your requirements and made the wrong changes.

I thought that you wanted to pause the vms while you backed stuff up but it appears that you want to shutdown then backup then startup again.

Try the sh scripts i have attached,

Below are the results I get, note I have a chromeOS Vm as well that it doesnt know how to shutdown.

Cheers Big Ears.





benharper$ sh ParallelsShutdownScript_Edit4DudeOnline.command

Found - Chrome OS, State = running

Tell Chrome OS to shutdown
Don't Know How To Shutdown a OS: chrome-1

Found - My Boot Camp, State = running

Tell My Boot Camp to shutdown
Shutdown a Win7 VM

&

benharper$ sh StartAllParallelsVMs.command

Found - Chrome OS, State = stopped

Chrome OS isnt running, starting it
Starting the VM...
The VM has been successfully started.
Chrome OS, State = running


Found - My Boot Camp, State = stopped

My Boot Camp isnt running, starting it
Starting the VM...
The VM has been successfully started.
My Boot Camp, State = running
 

Attachments

Doesnt Address on thing

Hi RujusMacBook,

You mentioned:
"2. Add an if statement in the second one to check if the VM Is already running or resuming, and if so, do nothing. "

the last post and scripts i put up wont address this, i dont know how to check if its in the proces of resuming?

Ben
 
BenHarper,

Thanks for the updated scripts, but I was actually looking for it to suspend rather than shut down the machines. How do I get it to just suspend them?

Thanks again!!

Eugene

PS Don't worry about testing for the "resuming" state. That isn't needed.
 
Hmmm

Originally when you tried the first script you wrote back to me that you received the output

Found - Windows 7, State = running
Windows 7 was running, pausing it
Pause the VM...
The VM has been successfully paused.

I assume that at this point the Vm was suspended and everything had worked as expected.
Was this not the desired outcome? Did you check was the VM not actually paused at this point?
If so how did you check as you need to check through the prlctl and not by attempting to interact with the vm as any form of interaction with the VM will immediately bring it back online.

Simply clicking start menu from the vm icon will wake the vm up very quickly.
The VM's seem to pause and resume extremely quickly, not like when you suspend windows and it takes a few minutes. (from inside windows, as apposed to outside windows through the VM manager like we are doing).
Are you aware that we are suspending the virtual environment that windows is running in and not actually sending a suspend command into windows - I am not an expert but i don't believe that windows will ever know that it was suspended, its entire hardware environment is suspended around it - AFAIK?


If I am not on the right track then you should give me a really clear rundown on what you are trying to do and how exactly you are doing it, dont leave anything out as I am having some trouble understanding the difficulty, I think that there is something lost in the (cant say translation as we are speaking english) but you know what I mean. It should be really simple but I cant see what might be going wrong. Give me some more info to work with.

Beers,
Ben.
 
Why do I get the feeling that your post was only made to advertise your diamonds?
Am I just jaded by forum hijacking advertisers?
HAHA Jaded =>Jade => metamorphic rock => like diamonds - yeah not that funny - like your add.
 
Back
Top