AppleScript for laptop deployment and maintenance

Working in AppleScript again for the first time in many years, I have written a series of scripts that I hope will combine into a single application to partially automate fall laptop prep. Each fall, we collect and maintain 350 teacher and laptop students, a grossly time-consuming effort. Many configuration tasks involve opening an application and changing settings — difficult to do quickly and with consistently high accuracy. AppleScript has the ability to program changes in configuration.

As quirky as AppleScript is, it provides an ideal bridge between OS X GUI user friendliness and command-line power. Partly, this is because AppleScript can call execute shell and Perl commands, so one has the power of all three languages available. For example, the script collects the user’s password from a GUI window and then calls the shell commands cp to copy a missing driver from our file server to the local system and lpadmin to add the printers. One includes the password in the shell statement using simple text concatenation. Same for the Entourage configuration — capture the user name from AppleScript’s “name of current user” and then pass it to the Entourage configuration statement. Finally, you can package the entire thing into an executable application for use in-house or distribution to users. Way cool.

The first script turns off automatic VLAN detection for Cisco Clean Access agent, a feature that causes processor utilization to spike every few seconds, reducing battery life. The second automatically adds 20 or so SMB printers to the Macintosh using lpadmin, a useful post-restore action. A third configures Microsoft Entourage for our mail server. Next, I would like to set the user’s server shortcuts, check for proper antivirus operation, and check Acrobat Reader version.

Please note: these scripts are currently under development (they’re not yet finished) and contain Catlin Gabel-specific settings. Please use them to inform your own script-writing. They won’t work as-is on your network. Many thanks to William M. Smith for a couple key tips. His Entourage/Exchange setup script is terrific if you’re looking for that function — better generalized than what I have provided below.

-- Cisco Clean Access patch for CCAAgent
-- Disables automatic VLAN detection

do shell script "whoami"
set theUser to the result

do shell script "cp /applications/ \"/users/" & theUser & "/library/application support/cisco systems/ccaagent/preference.plist\""

tell application "System Events"
set the thePListPath to "/Users/" & theUser & "/Library/Application Support/Cisco Systems/CCAAgent/preference.plist"
tell application "System Events"
tell property list file thePListPath
tell contents
set previousValue to value
set value to ({|VlanDetectInterval|:"0"} & previousValue)
end tell
end tell
end tell
end tell

display alert "Auto VLAN detection turned off!"

-- Adds Catlin Gabel printers

-- get desired divisions
set theDivisions to {"LS", "MS", "US", "All"}
choose from list theDivisions with prompt "Which division?"
set theDivision to result as text

-- get user name and password
do shell script "whoami"
set theUser to the result
set thePassword to text returned of (display dialog "User's network password" default answer "" with hidden answer)

-- configure lists of printers, names, and driver file locations
-- need to add Graceland

set lsPrinterNames to {"LS 2nd grade", "LS Comp Lab B&W", "LS Library B&W - Duplexing", "LS Library Color - Duplexing", "LS Office - Duplexing", "LS Spanish", "LS French", "LS Japanese"}
set msPrinterNames to {"MS Library Color - Duplexing", "MS Mobile Blue", "MS Office", "MS Secret Garden - Duplexing", "MS Upper Hall"}
set usPrinterNames to {"US Art B&S", "US Dant 9 - Duplexing", "US Dant 12 - Duplexing", "US Dant Main - Duplexing", "US Dant 10", "US Library B&W - Duplexing", "US Comp Lab Color - Duplexing", "US Math - Duplexing", "US Modern Lang 2 - Duplexing", "US Modern Lang 5 - Duplexing", "US Office - Duplexing", "US Science Main", "US Vollum Learning Center Copier", "US Vollum Main - Duplexing"}

set lsPrinterDrivers to {"HP LaserJet 2200.gz", "HP LaserJet 4250.gz", "HP LaserJet 4000 Series.gz", "HP Color LaserJet 4650.gz", "HP LaserJet 4000 Series.gz", "HP LaserJet 4MP.gz", "HP LaserJet 4MP.gz", "HP LaserJet 1320 Series.gz"}
set msPrinterDrivers to {"HP Color LaserJet 4600.gz", "HP LaserJet 2100 Series.gz", "HP LaserJet 4100 Series.gz", "HP LaserJet 5MP.gz", "HP LaserJet 1320 Series.gz"}
set usPrinterDrivers to {"HP LaserJet P2015.gz", "HP LaserJet 2200.gz", "HP LaserJet 4350.gz", "HP LaserJet 4000 Series.gz", "HP LaserJet 4100 Series.gz", "HP Color LaserJet 4600.gz", "HP LaserJet 2300.gz", "HP LaserJet 2300.gz", "HP LaserJet 2300.gz", "HP LaserJet 4250.gz", "HP LaserJet 2100 Series.gz", "RICOH Aficio MP 161", "HP LaserJet 4100 Series.gz", "HP LaserJet 4100 Series.gz"}

-- copy Ricoh driver from installer folder to system PPD library
tell application "Finder"
open location "smb://" & theUser & ":" & thePassword & "@cgsfiles01/installers"
end tell
do shell script "cp \"/Volumes/Active/RICOH Aficio MP 161\" \"/Library/printers/PPDs/Contents/Resources/\""

-- set range of printers to install
if theDivision is equal to "ls" then
set thePrinters to lsPrinters
set thePrinterNames to lsPrinterNames
set thePrinterDrivers to lsPrinterDrivers
end if
if theDivision is equal to "ms" then
set thePrinters to msPrinters
set thePrinterNames to msPrinterNames
set thePrinterDrivers to msPrinterDrivers
end if
if theDivision is equal to "us" then
set thePrinters to usPrinters
set thePrinterNames to usPrinterNames
set thePrinterDrivers to usPrinterDrivers
end if
if theDivision is equal to "All" then
set thePrinters to lsPrinters & msPrinters & usPrinters
set thePrinterNames to lsPrinterNames & msPrinterNames & usPrinterNames
set thePrinterDrivers to lsPrinterDrivers & msPrinterDrivers & usPrinterDrivers
end if

-- loop through printers
repeat with x from 1 to the number of items in thePrinters
do shell script "/usr/sbin/lpadmin -p " & item x of thePrinters & " -E -v smb://" & theUser & ":" & thePassword & "@CATLIN/CGSPRINT01/" & item x of thePrinters & " -P \"/Library/Printers/PPDs/Contents/Resources/" & item x of thePrinterDrivers & "\" -D \"" & item x of thePrinterNames & "\" -o printer-is-shared=false"
end repeat

-- do shell script "/usr/sbin/lpadmin -p ITVLMOFC -E -v smb://" & theUser & ":" & thePassword & "@CATLIN/CGSPRINT01/ITVLMOFC -P \"/Library/Printers/PPDs/Contents/Resources/HP Laserjet 4000 Series.gz\" -D \"IT Vollum Office\" -o printer-is-shared=false"

display alert "Printers successfully added!"

-- Configure Entourage

tell application "System Events"
set theUser to name of current user
set fullName to full name of current user
end tell
set thePassword to text returned of (display dialog "User's network password" default answer "" with hidden answer)

tell application "Microsoft Entourage"

make new Exchange account with properties {name:"Catlin Gabel", Exchange server settings:{address:"", requires SSL:"true"}, Exchange ID:theUser, domain:"catlin", full name:fullName, email address:theUser & "", LDAP server:"cgsdc00", search base:"ou=catlin users,dc=catlin,dc=edu", public folder server settings:{address:"", requires SSL:"true"}}

set enabled of schedule "Send & Receive All" to scheduled

end tell


  1. Peter Zingg says:

    Excellent post. My only issue with AppleScript is that I never seem to be able to handle errors that occur when running scripts. I’m moving to using ruby as my scripting language of choice; I’ve never mastered the syntax of shell scripts, and ruby has AppleScript ("rb-appscript") and Cocoa ("RubyCocoa") libraries so you can do just about anything Mac with it.

    There’s a also a nice open source project called puppet that uses automated ruby scripts to manage things like the stuff you’re doing. It does package and image deployment, monitoring, etc.

    WRT printer setups: I was working on setting up printer drivers using the lpadmin command similar to your script; the only thing I couldn’t find out is how to change the Default Printer setting you see in the Print & Fax Preferences from "Last Printer Used" to a specific printer. The lpadmin -d and lpoptions -d commands *did* change things in the cups printing system, but the Print & Fax Preferences remained unchanged–so I had to login manually to each computer to make the change…

  2. Richard says:

    You rock, Peter. I guess I’ll experience the limitations of error handling soon. I’m glad to hear that you have already walked a similar path. Could you make your Ruby scripts available? I’d love to see what tasks you accomplish with them.

    Re: default printers, I haven’t tried it myself, but how about lpadmin -d printer_name? I found a mention of it here:

    I’ll take a look at puppet.

    – Richard