Saturday, November 29, 2014

Disable "Add Account" Prompt on Mac

When you login to Gmail (or other popular web services) from Safari, you may be prompted to add the account to Mail, Calendar, Contacts, and other programs that Apple bundles with Macs. While very helpful for home users, this can be a problem for schools. Students and faculty could potentially have many gigabytes of data in Gmail, making the login process take longer and using up limited server space.

With more and more schools moving to Google Apps For Education, this is becoming a more common issue. Depending on your system, it could also mean longer waits during login and logout. If you store user data on a server, its also a lot of unnecessary disk space used (and used again in your backup system.)

To prevent this, I wrote the following script and included it in my Mac setup process inside Deploy Studio. If you use it in your environment, replace "YOUR-DOMAIN-HERE" with your Google Apps domain or remove it. If you want to disable the "Add Account" prompt for a service not listed in this script, just add it after "" in quotation marks.


defaults write /Library/Preferences/ DomainsToNeverSetUp -array "YOUR-DOMAIN-HERE" "" "" "" "" "" "" "" ""

exit 0

If your Macs are already in service and you don't want to image them again, this script will still work. Just push it to them and run it as the user "root". You can do this in Apple Remote Desktop, Casper, FileWave, Munki (as a postflight script in a PKG installer), or other tools.

Sunday, November 16, 2014

Change Default Dock Items

When users login to a new version of MacOS for the first time, it will fill their Dock with new icons that Apple has chosen. This might not always meet the needs of your business, school, or organization. For example, if you have your users' home directories on a file server, you might not want to encourage your users to use iMovie, GarageBand, iTunes, and iPhoto due to their tendency to use large amounts of disk space. If you use Google Apps for Work or Google Apps for Education, you might not want to present Mail, Maps, or Calendar. Each institution must make their own decision about what is best for them.

At my job, we use home directories on a file server with anywhere from 35 to 100 users on it at the same time. As you can imagine, this means a classroom of 25 students using iMovie could cause the entire school to experience serious slow-downs. We also use Google Apps for Education, so I don't want to encourage users to utilize Apple's Mail program. That would mean several GB more disk space used per user over hundreds of users. In other words, my servers would unnecessarily have about an extra 1TB (or more) disk space used, my backup system would get filled up, and everyone's Macs would be much, much slower.

To solve this, I give my end users an empty Dock. They're shown how to use Google Apps for Education and how to add items to the Dock. Then when they think "I want to see my email," they go to Gmail instead of the Mail program.

To do this, I wrote the following script and put it in our Deploy Studio server. It runs just after the Mac is imaged with its OS.

(Note: This is for MacOS 10.9. For MacOS 10.7, remove the # from the beginning of the appropriate line and add it to the beginning of the line for 10.9.)

# This script will attempt to avoid adding all of Apple's default items from the
# Dock for new users.  This default behavior of MacOS is very useful for home
# users but terrible for institutional deployments, where the needs of Apple
# and the needs of the institution which purchased Macs might not be aligned.
# 2014-04-03-1615, Jaime Kikpole

DEFAULTS="/System/Library/CoreServices/" # For 10.9
# DEFAULTS="/System/Library/CoreServices/" # For 10.7

FIXUP="/Library/Preferences/" # For 10.7

echo Changing default settings for the Dock for new users...

if [ -w ${DEFAULTSFILE} ]; then
 echo - Changing settings in "${DEFAULTS}"...
 defaults write ${DEFAULTS} persistent-apps ""
 defaults write ${DEFAULTS} persistent-others ""
 chmod +r ${DEFAULTS}
 echo ...done.
 echo "${DEFAULTSFILE}" not found or writable.

if [ -w ${FIXUPFILE} ]; then
 echo - Changing settings in "${FIXUP}"...
 defaults write /Library/Preferences/ add-app ""
 chmod +r ${FIXUP}
 echo ...done.
 echo "${FIXUPFILE}" not found or writable.

echo End of script.

Tuesday, November 11, 2014

Backup Configuration Files

Anyone who manages a Unix-like system has edited a configuration file from time to time.  At an absolute minimum, you should copy these files before editing them.  Otherwise, you could get through a few lines of editing, break something (or just want to go back to your old setup), and not know how to go back.

Here is a quick trick I came up with for handling this.  There are better ways, but this can be dropped right into any Unix-like system with very little effort. That easily includes MacOS, Linux, and FreeBSD.

First, I started with this trick from

cp file.txt{,.backup}

This will copy file.txt to file.txt.backup .

Unfortunately, the next time its done, file.txt.backup will be overwritten and the history of our changes over time will be lost.

So I decided to end the backup files with the date. Done correctly, this will alphabetize them into chronological order and allow some rudimentary change-tracking in the future using the diff command. So let's look at this:

date "+%Y%m%d%H%M%S"

It outputs the current date and time in YYYYMMDDHHMMSS format. In other words, it prints out the year, then month, then day of month, then the time. So 9:59am on July 11, 2014 will come out as 201407110959.

Note that this is done with "padding zeros" to make sure that it alphabetizes into chronological order. You can see it in the "07" for July, which will now come before December. This is because 07 is alphabetically before 12, even though July and Jul are alphabetically after December and Dec.

So using that and the cp command from earlier, we now have this.
cp file.txt{,.`date "+%Y%m%d%H%M%S"`}

This copies file.txt to file.txt.<timestamp>. Using the example date above (9:59am on July 11, 2014), that would be file.txt.201407110959. This is the effect we want.

In a bash shell script, "$1" references the first string after the command, as parsed by whitespace delimiting.

So using that, we get this shell script:

cp $1{,.`date "+%Y%m%d%H%M%S"`}
Let's put that in a file called and then make sure its executable with chmod 755 This allows "./ file.txt" to copy file.txt to file.txt.<timestamp> without having to manually calculate the timestamp.

Name this "backup" and copy it to your ~/bin, /usr/local/custom, or some other location in your $PATH. Then set it to chmod 0755, if you haven't done so yet.
The next time you have to edit a configuration file, just type "backup config-file.txt" before you edit it.

So, to re-cap:
  1. Make a file called "backup" and put the above two line script in it.
  2. Put "backup" someplace where it will be in your $PATH, such as ~/bin or /usr/local/bin or /usr/local/custom.
  3. Make sure that location is actually in your $PATH.
  4. Use chmod 755 /path/to/backup to make sure its executable.
  5. From now on, before editing configuration files you should type "backup <config file>" to make a quick copy that you can revert to.
Note: There are better ways to track your server's configuration changes, but they're not always an option. Sometimes policy gets in the way. Sometimes convincing the other system administrators to use the tools is hard. This solution should work on any system and provides a predictable and reliable tool with a minimum of training and without installing any additional software. I recommend starting with this and, where available, eventually moving to tools like RCS or git.