Automating the Mundane…Scripting for VMWare Fusion Efficiency

Growing up, it was not uncommon to hear someone quote the phrase “you tell me what you think about when you do not have to think, and I’ll tell you what you are.”  It’s a quote that can be deep, philosophical and ignite some serious introspection.

For me, the answer is easy.  It’s efficiency.  My brain is constantly chewing on how to make whatever insufferable process I’ve been experiencing in the last hour, day, week, etc; more palatable, more efficient, less…well, less sufferable.

Now, I know that declaring war on inefficiency should not be humanity’s primary purpose in life; not everything is a race to the finish line with as limited wasted movement as possible, but tell that to some other guy who’s brain doesn’t dissect every tiny amount of wasted time as potential opportunity for improvement.

When a former employer was asked by a potential new employer what my biggest weakness was, he responded with “well, I don’t know if this is exactly a weakness, but Bennett will constantly be looking for a way to improve a process, to make things more streamlined, even if he spends weeks devising a plan to save a minute’s worth of work during an 8 hour work day.”

Personally I hear that and I think, “wow, look how inefficient I’m being on spending such time to save so little.”

Nonetheless, hear I sit, a self-proclaimed efficiency hunter ready to tell you how I spent last week efficiency hunting within my daily workflow, to save not only time, but frustration and to improve the consistency of my work.

My daily routine as a LANDESK Sales Engineer consists of demonstrating one or more of our products to potential customers.  Due to the number of different products desired to be seen and the potential use cases from the customer that may require an integration demo, I may have up to 8 different virtual machines that need to be spun up.

In order to maintain consistency in my demo environment, I will take snapshots of each VM so I can demo the full capabilities of the software products and quickly reset back to square one for the next demo.

As such, I’m often starting a number of machines, stopping a number of machines, snapshotting them, reverting to snapshots, deleting old snapshots and even just needing to see what snapshots I’ve created.  All of this can be a bit cumbersome when you do it many times a day.

So when I received my new MacBook Pro last week, my efficiency brain kicked in, it was time to automate the entire process.  Luckily for me, VMWare has a utility that allows command line access to do all of the starting and stopping of the machines, as well as the snapshot management.

Perfect right?  Well almost, I didn’t want to write my own script, I wanted to just borrow someone else’s.  Alas, I scoured page one and even page 2 of Google (I know, page 2!) for a number of different search criteria hoping to find a hit, only to come away empty handed.

My efficiency brain wouldn’t let me just quit and give up though.  So I went to work and spent from 9 PM to 3 AM writing my own script and am now making that script available to you for your own efficiency pleasure.

Enjoy!  All you should have to do is fill out the variables at the top and you’ll soon be on your way to VMWare Fusion Management efficiency bliss.  I’ve saved my script as a .command file so I can execute directly from my desktop.

#/bin/bash 


# Version history 
# v1.0 - initial release
# 

# Add the paths to all of your VMs
declare -a arrayPathForVMs=("Documents/VMs/LDSERVER/LDSERVER.vmx" "Documents/VMs/OSX/OSX.vmx" "Documents/VMs/Win8/Win8.vmx")


# Create a directory location variable
vmrunPath="/Applications/VMware Fusion.app/Contents/Library/vmrun"
setScriptPath="$HOME"


while :
do
 clear
 cat <<EOF
 =========================================
 VM Fusion Management
 -----------------------------------------
 Please enter your choice:
 
 (1) Start VMs
 (2) Revert to a Snapshot
 (3) Create a Snapshot
 (4) Delete a Snapshot
 (5) List Snapshots
 (6) Suspend all VMs
 (7) Exit
 
 -----------------------------------------
EOF
 read -n1 -s
 case "$REPLY" in
 

 "1")
 echo "Starting your VMs..."
 cd "${setScriptPath}"
 for i in "${arrayPathForVMs[@]}"; 
 do
 echo "Launching" "$i"
 "${vmrunPath}" -T fusion start "${i}";
 done
 echo "All VMs started."
 Sleep 2
 exit 0
 ;;

 "2")
 echo -n "Which snapshot do you want to revert to?"
 read snapshotName
 cd "${setScriptPath}"
 for i in "${arrayPathForVMs[@]}"; 
 do
 echo "Reverting to" "$snapshotName" "on" "$i"
 "${vmrunPath}" -T fusion revertToSnapshot "${i}" "${snapshotName}";
 done
 echo "All VMs reverted."
 Sleep 2
 exit 0
 ;;

 "3") 
 echo -n "What will the snapshot name be?"
 read newSnapshotName
 cd "${setScriptPath}"
 for i in "${arrayPathForVMs[@]}"; 
 do
 echo "Creating" "$newSnapshotName" "on" "$i"
 "${vmrunPath}" -T fusion snapshot "${i}" "${newSnapshotName}";
 done
 echo "Snapshots created for all VMs"
 Sleep 2
 exit 0
 ;;

 "4")
 echo -n "Are you sure you want to delete a snapshot (y/n)? "
 read answer
 if echo "$answer" | grep -iq "^y" ;then
 echo -n "What snapshot do you want to delete?"
 read snapshotToDelete
 cd "${setScriptPath}"
 for i in "${arrayPathForVMs[@]}"; 
 do
 echo "Deleting" "$snapshotToDelete" "on" "$i"
 "${vmrunPath}" -T fusion deleteSnapshot "${i}" "${snapshotToDelete}";
 done
 echo "Snapshot deleted for all VMs"
 read -p "Press [Enter] to close."
 exit 0
 else
 echo "No changes have been made."
 read -p "Press [Enter] to close."
 exit 0
 fi
 ;;

 "5")
 echo "Listing your snapshots..."
 for i in "${arrayPathForVMs[@]}"; 
 do
 echo "Snapshots for" "$i"
 "${vmrunPath}" -T fusion listSnapshots "${setScriptPath}/""${i}";
 done
 echo "All snapshots displayed"
 read -p "Press [Enter] to close."
 exit 0
 ;;
 
 
 
 "6")
 echo "Suspending your VMs..."
 cd "${setScriptPath}"
 for i in "${arrayPathForVMs[@]}"; 
 do
 echo "Suspending" "$i"
 "${vmrunPath}" -T fusion suspend "${i}";
 done
 echo "All VMs suspended."
 Sleep 2
 exit 0

 ;;
 
 "7")
 echo "Exiting..."
 exit 0

 ;;
 
 "Quit")
 break
 ;;

 *) echo invalid option;;
 esac
done

How to Remove Adobe Flash with LANDESK Management Suite

Do you think it’s time to remove Adobe’s Flash Player from your OS X boxes?  One glance at the Common Vulnerabilities and Exposure’s latest update should get you motivated!

If that doesn’t work, check out Ars Technica’s latest blog on the details of the two 0-day exploits.

It is passed time to remove Flash.   Get it out of your environment and get it out now.

Luckily, removing Flash is not very difficult.  With the simple script below, Flash can be quickly relegated to the depths of trash bin, never to be recovered.

#!/bin/bash

UninstallFlash=(

"/Applications/Utilities/Adobe Flash Player Install Manager.app"

"/Library/Internet Plug-Ins/Flash Player.plugin"

"/Library/Internet Plug-Ins/flashplayer.xpt"

"/Library/PreferencePanes/Flash Player.prefPane"

"/Library/Receipts/Adobe Flash Player.pkg"

)

for FlashObject in "${UninstallFlash[@]}"; do

rm -rf "${FlashObject}"

done

If you’re a LANDESK customer, you can create a package file out of the script if you would like, following the steps outlined in the previous blog post on the “The 3 Step Process of Bundling Scripts with Pkgbuild for a Payload-less Package Deployment

For our Adobe Flash instance, an abbreviated version of 3 steps will be as follows:

Step 1 – Create a “Remove Adobe Flash” folder structure and build script for the PkgBuild utility.  Insert the code below for your “package_the_script.sh” script, changing your identifier as needed.

#!/bin/bash

PKG_ID=Remove_Adobe_Flash

sudo pkgbuild --identifier com.appleintheenterprise.$PKG_ID --nopayload --scripts ./scripts ./$PKG_ID.pkg

 

Once saved, run the command “sudo chmod a+x package_the_script.sh” to ensure execute permissions are set.  You may also want to sign the package if using Gatekeeper.

Step 2 – Copy the Uninstall flash script in the beginning of the article into the Scripts/postinstall file

#!/bin/bash

UninstallFlash=(

"/Applications/Utilities/Adobe Flash Player Install Manager.app"

"/Library/Internet Plug-Ins/Flash Player.plugin"

"/Library/Internet Plug-Ins/flashplayer.xpt"

"/Library/PreferencePanes/Flash Player.prefPane"

"/Library/Receipts/Adobe Flash Player.pkg"

)

for FlashObject in "${UninstallFlash[@]}"; do

rm -rf "${FlashObject}"

done

Step 3 – Create the Remove_Adobe_Flash Package by opening Terminal and browsing to wherever you saved your package_the_script file.  Once there, type “sudo ./package_the_script.sh”.  So doing should create your uninstaller package.  Now, zip the pkg file and copy it to your software distribution share and build your LANDESK deployment package.

  • From the LANDESK Console, open Tools > Distribution > Distribution Packages
  • Inside the menu tree, highlight My Packages or Public Packages and then select the New Package button on the menubar and select New Macintosh Package
  • Give the package a name, description and point the primary file to the zip file created previously
  • Fill out the Metadata details if desired
  • Save the package

To create a task to deploy your LANDESK package, walk through the steps below:

  • Right click on the package created and select Create Scheduled Task
  • Target the desired machine(s), user(s) or query(ies)
  • Right click on the task and select properties
  • Set the desired Task type under Task Settings
  • If you desire the end user to be able to initiate the task, set the radio button in the Portal Settings to either Recommended or Optional, otherwise set it to Required and it will automatically begin the upgrade during the next maintenance window
  • Change the Reboot Settings on the task to one that forces a reboot
  • Schedule the task

To validate your success, browse to http://www.adobe.com/software/flash/about/ on the machine and you should see that the plug-in is missing.

How to Install Microsoft Office 2016 for Mac Using LANDESK Management Suite

Goodbye 2011 and hello 2016!  After five long years, Microsoft has finally replaced its outdated and very un-Macish Office 2011 product with an ultra-sleek and modern Office 2016 for Mac. Re-written from the ground up, Microsoft is promising an “unmistakably Office” experience; something we Mac users have not previously enjoyed without compromising the Mac experience itself.

The one major caveat for the Office 2016 for Mac release…you must be an Office 365 subscriber, or you must be a student to get access to the product today. If you don’t fall into one of those two categories, you’re going to need to hold tight. While the full details are not yet known, such as the exact release date or price, the one-time product purchase option will have you waiting until September sometime. If you don’t feel you can wait that long, head over to office.com/mac and become a subscriber today.

Kirk Koenisbauer, the corporate vice president for the Office Client Applications and Services team, writes on the Office Blog:

“Today we are taking a big step forward for Mac® users—Office 2016 for Mac is now available in 139 countries and 16 languages. Based on feedback from the great Mac Office community, we’ve made major updates to each of the apps, and we couldn’t be more pleased to deliver it first to our Office 365 customers.”

So just how can you get this wonderful new Office suite installed on all of your Macs? Just sign in to your office.com/myaccount area, or into your personalized corporate portal, hit the Office 365 settings cog icon and then navigate to the Software section.

Once on the Software page, you’ll see the Install button. Click it and the 1.1 GB .pkg installer will begin to download.

OfficeInstallButton

When you have the installer downloaded, the fun can finally begin. To deploy it out to all of your OS X machines, you’re going to want to use LANDESK Management Suite.

Remember, with the install being tied to your Office 365 account, there are no customization options that need to take place with the installer itself. And, as a step of precaution, zip up the installer since it’s a pkg file type, as you don’t want Windows to think it would be a good idea to mess with the permissions on the installer files themselves. When you’ve completed zipping the installer, place it into your software distribution share you use for LANDESK.

From there, you’ll need to create a LANDESK Mac distribution package. The nine-step process below contains information on how to create the package:

  1. Open the LANDESK Console
  2. Navigate to the top menu bar, select Tools > Distribution > Distribution Packages.
  3. In the lower left menu tree, highlight My Packages or Public Packages from within the Distribution Packages window
  4. On the Distribution menubar, press the New Package button and select New Macintosh Package.
  5. Give the package a name, something like Office 2016 for Mac
  6. Provide a description if desired
  7. Set the primary file to the zip file you previously transferred to your software distribution folder
  8. Fill out the Metadata details if desired
  9. Save the package

Office 2016 Package

With the LANDESK Mac package created, you now just need to schedule a task for deployment. This too, is a pretty simple process.

  1. Right click on the Office 2016 for Mac package created and select Create Scheduled Task
  2. From the network view, select and drag the desired machine(s), user(s) or query(ies) and drop them onto the task
  3. Now, right click on the task and select properties
  4. Set the desired Task type under Task Settings as to whether you want a push, a policy or a hybrid of the two types in a policy-supported push.
  5. If you desire the end user to be able to initiate the task, set the radio button in the Portal Settings to either Recommended or Optional, otherwise set it to Required and it will automatically begin the upgrade during the next maintenance window
  6. Change the Reboot Settings or Distribution and Patch settings if desired
  7. Set the schedule task settings with the appropriate start time

Required or Recommended

With that, you can sit back and watch. On my 2015 MacBook Pro, the install took about five minutes. However, it’s worth noting, the Office 2016 for Mac installer does not remove Office 2011 for Mac. If you want it removed, you’re going to need to create a LANDESK Uninstall Mac package and deploy it in conjunction to the Office 2016 for Mac installer.

Once installed, the first time any one of the five applications (Word, Excel, Outlook, PowerPoint of One Note) is launched, it will prompt the end user to sign in and activate.

Sign In to Activate

The 3 Step Process of Bundling Scripts with Pkgbuild for a Payload-less Package Deployment

We all love Terminal and its simplicity, right?  After all, that’s why we’ve written scripts to help us in our enterprise Mac management, just so we can spend more time in Terminal.

Can you sense my sarcasm?

While Terminal is definitely simple, it’s quite probable that it’s not your love unless you’re a programmer or have a programming background. For the rest of us, Terminal is the place we go when we’re Googling how to accomplish some task; because the instructions we find have been written by a Terminal lover — despite the fact there is quite likely a fantastic graphical interface method to use.

Well, today is no different.  Chances are you’re a LANDESK administrator and found this page because you want to figure out how to deploy a script you’ve written and the easiest way to do that is to push a package inside of LANDESK’s Management Suite.

To convert our script into a package, we’re going to use Terminal and Apple’s pkgbuild command line tool.

Should I preface now there are graphical options to accomplish what we’re going to do? See Iceberg.  Apple, however, has deprecated their graphical package builder, PackageMaker, relegating it to the far flung corners of their developer website, making it difficult to even find.

Since there are a number of blogs explaining the granular details around pkgbuild available on the Internet, The Grey Blog being one of them, I’m only going to focus on the basics of creating a payload-less package using the -nopayload option on pkgbuild.

As outlined in the man pages for pkgbuild, the -nopayload option “indicates that the package will contain only scripts, with no payload.”  In other words, we’re not installing bits, we’re simply going to invoke some commands the OS can interpret as prescribed in our scripts bundled inside the package.

Using the example from the previous blog post, we’re going to take the script we wrote to create an XML file that the LANDESK inventory scanner can pick up and deliver to the LANDESK core server.  However, any script will work with the steps below, so manipulate as needed.

Our 3 step process is as follows:

  1. Create the folder structure and build script for pkgbuild
  2. Write your script
  3. Create the package
Step 1 – Create the Folder Structure and Build Script for PkgBuild

Alright, let’s create a folder to house our scripts.  In my example, using Finder, I’m going to create a new folder on my Desktop called SMART HD Detection.  Secondly, I’m going to create a second folder inside my SMART HD Detection folder titled ‘scripts’.

Using TextWrangler or Xcode or some other text editor, I need to create a blank file called postinstall and save it to the scripts folder.  We’ll come back to it later.

Now I need to create a my pkgbuild script.  Again, using TextWrangler or Xcode, create a file  titled package_the_script.sh and save it to the primary folder you created, in my example, the SMART HD Detection.

SMARTHDDetection

We will now add the requisite pkgbuild code to create a payload-less inside the package_the_script.sh script.  This script will be quite generic and essentially reusable for all of the packages you need to create now and in the future.

The code is:


PKG_ID=Gather_SMART_Disk_Status

sudo pkgbuild --identifier com.appleintheenterprise.$PKG_ID --nopayload --scripts ./scripts ./$PKG_ID.pkg

Alright, let’s break this down by the line of code.  Hopefully the #!/bin/bash is straight forward for you.

PKG_ID=Gather_SMART_Disk_Status is specifying a variable, PKG_ID, and it will be used as the name of the package we’re going to create.  You’ll want to replace Gather_SMART_Disk_Status with the desired name of your package.

The sudo pkgbuild has several arguments, which will break down individually. Please note, however, there are a number of other arguments you may want to add.  Again, refer to the man pages.

The –identifier is specifying you as the creator, so add in your domain or unique identifier bundled with the package ID.  The OS X Installer recognizes a package as being an upgrade to an already-installed package only if the package identifiers match, so it is advisable to set a meaningful, consistent identifier when you build the package.

The –nopayload option tells pkgbuilder we will be creating a payload-less package.

The –scripts ./scripts identifies the location of our script files that we want bundled up.

Now we can wrap everything up and name it ./$PKG_ID.pkg. Using the name variable allows us to reuse the same command line over and over.

Lastly, I need to save the script and mark it for execution by opening Terminal and browsing to my folder location.  In my instance, it’ll be ~/Desktop/“SMART HD Detection”  Once inside the folder structure, I’ll run the command “sudo chmod a+x package_the_script.sh”.

As can be seen, I didn’t sign this package.  If you need your package to work with Gatekeeper introduced in OS X 10.8, you’re going to need to use the –sign argument.

Step 2 – Write Your Script

Again, using TextWrangler or Xcode, I’m going to open the postinstall I created earlier and write my custom script into it.  My script is going to detect the status of the SMART HD.  However, you can write scripts to install printers, run software updates, reboot the machine, or any other number of tasks.  Just write or copy your script into the postinstall file and save it.

#!/bin/bash

OUTPUT_FILE="/Library/Application Support/LANDesk/CustomData/SmartHardDriveStatus.xml"

echo "&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;" &gt; "$OUTPUT_FILE"

echo "&lt;SMART_info&gt;" &gt;&gt; "$OUTPUT_FILE"

diskutil list | egrep "^/" | while read drive
do
     DRIVE=`basename $drive`
     STATUS=`diskutil info $drive | grep SMART | awk '{ $1=$2="" ;print $0 }'`
     echo "&lt;$DRIVE&gt; $STATUS &lt;/$DRIVE&gt;" &gt;&gt; "$OUTPUT_FILE"
done

echo "&lt;/SMART_info&gt;" &gt;&gt; "$OUTPUT_FILE"
Step 3 – Create the Package

OK, we’re nearly there.  All I need to do now is to execute the script ‘package_the_script.sh’ and it will run pkgbuild and create the package for us.

To do this, again open Terminal and browse to your folder structure you created.  Again, mine will be ~/Desktop/“SMART HD Detection”

Once there, type “sudo ./package_the_script.sh”.  So doing should create a package inside your folder with the name you provided under the PKG_ID variable.

That’s it, we’re all done.  We can now double click on our package inside of Finder and it will execute.

If you desire to push the script with LANDESK Management Suite to one or more machines, you just will need to zip the pkg file and copy it to your software distribution share.

To build the LANDESK software package that’ll distribute your shiny new package, do the following:

  • From the LANDESK Console, open Tools > Distribution > Distribution Packages
  • Inside the menu tree, highlight My Packages or Public Packages and then select the New Package button on the menubar and select New Macintosh Package
  • Give the package a name, description and point the primary file to the zip file created previously
  • Fill out the Metadata details if desired
  • Save the package

To create a task to deploy your LANDESK package, walk through the steps below:

  • Right click on the package created and select Create Scheduled Task
  • Target the desired machine(s), user(s) or query(ies)
  • Right click on the task and select properties
  • Set the desired Task type under Task Settings
  • If you desire the end user to be able to initiate the task, set the radio button in the Portal Settings to either Recommended or Optional, otherwise set it to Required and it will automatically begin the upgrade during the next maintenance window
  • Change the Reboot Settings on the task to one that forces a reboot
  • Schedule the task