Image cleanup script
UPDATE 1/23/09: some commenters asked about cleanup of the LKDC (new in Leopard) – I’ve added that to the script.
At the Macworld Expo 2009 Power Tools System Imaging and Deployment session today, I was asked to share a “checklist” of cleanup steps I use when building images the “classic” way. (The InstaDMG methodology of image building makes cleanup steps unneeded.)
Here’s a cleaned-up version of the script I use, with site-specific stuff removed for the most part.
If you use this, you’ll need to modify the paths to any local user home directories for any local users you have on your image. There are generic examples for a local admin user named “admin” and the root user (which if you never login as root, you shouldn’t have to clean up!)
#!/bin/sh
#this script does some cleanup in preperation for building an image
#best to run this from single user mode, or at least right before you shutdown
#run this as root, or with sudo rights
#set machine names back to generic
/usr/sbin/scutil --set ComputerName "OSX_Standard_Image"
/usr/sbin/scutil --set LocalHostName "osximg"
#delete swapfiles
rm /private/var/vm/swapfile*
#delete volume info DB
rm /private/var/db/volinfo.database
#cleanup local admin's home dir
rm -rf /Users/admin/Desktop/*
rm -rf /Users/admin/Documents/*
rm -rf /Users/admin/Library/Caches/*
rm -rf /Users/admin/Library/Recent\ Servers/*
rm -rf /Users/admin/Library/Logs/*
rm -rf /Users/admin/Library/Keychains/*
rm -rf /Users/admin/Library/Preferences/ByHost/*
rm -f /Users/admin/Library/Preferences/com.apple.recentitems.plist
rm -rf /Users/admin/Movies/*
rm -rf /Users/admin/Music/*
rm -rf /Users/admin/Pictures/*
rm -rf /Users/admin/Public/Drop\ Box/*
#cleanup root's home dir
rm -rf /private/var/root/Desktop/*
rm -rf /private/var/root/Documents/*
rm -rf /private/var/root/Downloads/*
rm -rf /private/var/root/Library/Caches/*
rm -rf /private/var/root/Library/Recent\ Servers/*
rm -rf /private/var/root/Library/Logs/*
rm -rf /private/var/root/Library/Keychains/*
rm -rf /private/var/root/Library/Preferences/ByHost/*
rm -f /private/var/root/Library/Preferences/com.apple.recentitems.plist
rm -rf /private/var/root/Public/Drop\ Box/*
#clean up global caches and temp data
rm -rf /Library/Caches/*
rm -rf /System/Library/Caches/*
rm -rf /Users/Shared/*
rm -f /private/etc/ssh_host*
#network interfaces - this is regenerated on reboot and can differ on different hardware
rm /Library/Preferences/SystemConfiguration/NetworkInterfaces.plist
#Leopard - cleanup local KDC, see http://support.apple.com/kb/TS1245
/usr/sbin/systemkeychain -k /Library/Keychains/System.keychain -C -f
rm -rf /var/db/krb5kdc
/usr/bin/defaults delete /System/Library/LaunchDaemons/com.apple.configureLocalKDC Disabled
#log cleanup. We touch the log file after removing it since syslog
#won't create missing logs.
rm /private/var/log/alf.log
touch /private/var/log/alf.log
rm /private/var/log/cups/access_log
touch /private/var/log/cups/access_log
rm /private/var/log/cups/error_log
touch /private/var/log/cups/error_log
rm /private/var/log/cups/page_log
touch /private/var/log/cups/page_log
rm /private/var/log/daily.out
rm /private/var/log/ftp.log*
touch /private/var/log/ftp.log
rm -rf /private/var/log/httpd/*
rm /private/var/log/lastlog
rm /private/var/log/lookupd.log*
rm /private/var/log/lpr.log*
rm /private/var/log/mail.log*
touch /private/var/log/lpr.log
rm /private/var/log/mail.log*
touch /private/var/log/mail.log
rm /private/var/log/monthly.out
rm /private/var/log/run_radmind.log
rm -rf /private/var/log/samba/*
rm /private/var/log/secure.log
touch /private/var/log/secure.log
rm /private/var/log/system.log*
touch /private/var/log/system.log
rm /private/var/log/weekly.out
rm /private/var/log/windowserver.log
touch /private/var/log/windowserver.log
rm /private/var/log/windowserver_last.log
rm /private/var/log/wtmp.*
January 6, 2009 at 4:36 pm
I’m kind curious as to the reason you chose to set the ComputerName and LocalHostName to different values?
January 6, 2009 at 4:56 pm
Because I can! Seriously, there was a reason in the past (and the values in the script I posted are not the ones in the script I actually use), but I cannot really remember why…
January 7, 2009 at 12:05 pm
Script is being cut off a little…would be nice to be able to copy/paste it if possible.
January 7, 2009 at 12:15 pm
Copy and paste works for me (using Safari as the web browser) — all text is preserved and the long lines come back…
-Greg
January 7, 2009 at 4:07 pm
Hi Greg
Noticed that you are not doing anything with the LKDC, in this scipt, are you cleaning this up elsewhere in your imaging process ? Interested in your throughts and comments on this. Cool script by the way…
Thanks as always for contibuting to the Apple community !
January 7, 2009 at 4:22 pm
I have to admit that I’m not doing anything with the LKDC stuff, and I probably should be…
January 8, 2009 at 12:27 am
The LKDC caught my eye as well (only because I’ve experienced the pain of not resetting it!) Now I always do:
rm -rf /var/db/krb5kdc
/usr/libexec/configureLocalKDC
thanks!
February 18, 2009 at 12:16 pm
here’s the script we use here as a contribution to greg’s awesome script. we like removing a few other items before imaging as well.
FYI: we have users accounts called “workstation” and “fieldtech” so you’ll see those calls in our script. obviously, you’ll want to add your own user account names if you have them.
#!/bin/sh
# the j. paul getty scrubbing tool, ©2007, David Koff
# used to finalize a drive for use as an images for cloning.
# may not be used without including these three lines of code.
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo This script will prepare your Macintosh for being imaged.
echo Certain system files will be deleted. Additionally, the
echo ‘Workstation’ user account will be copied into the ‘english.lproj’
echo folder for use as a template for creating new user accounts.
echo “”
echo “”
echo “”
echo “The script will take about one minutes to run. Are you ready (y/n)?”
echo “”
echo “”
echo “”
read answer
if [ $answer = "n" ]; then
echo “”
echo “”
echo “”
echo OK. Script will now terminate. Thank you.
exit 0
fi
cd /
echo “”
echo “”
rm -rf /Library/Logs/
rm -rf /Users/workstation/Library/Logs/
rm -rf /Users/fieldtech/Library/Logs/
echo “User Account Log Files, and Main Library Logs have been deleted!”
echo “”
sleep 1
echo “”
echo “”
rm -r /Messages\ Received/*
rm -r /Users/workstation/Downloads/*
rm -r /Users/fieldtech/Downloads/*
rm -r /var/root/Downloads/*
echo “The downloads & Messages Received folders have all been deleted!”
echo “”
sleep 1
echo “”
echo “”
rm -rf /var/vm/swap*
echo “swapfiles deleted!”
echo “”
sleep 1
rm -rf /var/db/volinfo.database
rm -rf /var/db/volinfo.database
echo “volinfo databases deleted!”
echo “”
sleep 1
rm -rf /var/db/BootCache.playlist
echo “bootcaches deleted!”
echo “”
sleep 1
rm -rf /System/Library/Caches/*
echo “library caches deleted!”
echo “”
sleep 1
rm -dr /var/root/Library/Caches/*
rm -dr /Users/workstation/Library/Caches/*
rm -dr /Users/fieldtech/Library/Caches/*
echo “all individual user library caches deleted!”
echo “”
sleep 1
rm -rf /System/Library/Extensions.kextcache
echo “extension kextcaches deleted!”
echo “”
sleep 1
rm -rf /tmp/*
rm -rf /var/tmp/*
echo “temp files deleted!”
echo “”
sleep 1
rm -rf /.Trash
echo “trash files deleted!”
echo “”
sleep 1
rm -f /var/vm/sleepimage
rm -rf /.com.apple.NetBootX/
echo “sleepimage files deleted!”
echo “”
sleep 1
rm -rf /Users/workstation/Library/Preferences/ByHost/
rm -rf /Users/workstation/Library/Keychains/login.keychain
echo “ByHost files and keychains deleted from workstation account!”
echo “”
sleep 1
rm -rf /Users/fieldtech/Library/Preferences/ByHost/
rm -rf /Users/fieldtech/Library/Keychains/login.keychain
echo “ByHost files and keychains deleted from fieldtech account!”
echo “”
sleep 1
rm -rf /Library/Preferences/ByHost/
echo “ByHost files deleted from root account!”
echo “”
sleep 1
rm -rf /Library/NETAepoagt/scratch/props.ini
echo “the epo/virus props.ini file has been deleted!”
echo “”
sleep 1
rm -rf /Library/NETAepoagt/scratch/props.bak
echo “the epo/virus props.bak file has been deleted!”
echo “”
sleep 1
rm -rf /Users/workstation/Library/Preferences/com.apple.recentitems.plist
rm -rf /Users/fieldtech/Library/Preferences/com.apple.recentitems.plist
rm -rf /var/root//Library/Preferences/com.apple.recentitems.plist
echo “the apple menu recent items list has been deleted!”
echo “”
sleep 1
defaults delete com.apple.finder FXRecentFolders
echo “Finder’s Go -> Recent Folders list has been deleted!”
echo “”
sleep 1
rm -dr /Users/workstation/Library/Recent\ Servers
rm -dr /Users/fieldtech/Library/Recent\ Servers
rm -dr /private/var/root/Library/Recent\ Servers
echo “all recent servers been deleted!”
echo “”
sleep 1
rm -r /System/Library/User\ Template/English.lproj/*
echo “the english.lproj folder has been emptied!”
echo “”
echo “”
echo “please stand by: the workstation user account is copied as a template”
echo “for creating new user accounts. THIS TAKES ABOUT 30 SECONDS.”
echo “”
echo “”
cp -Rp /Users/workstation/* /System/Library/User\ Template/English.lproj/
echo “the workstation account has been duplicated to the english.lproj folder!”
sleep 2
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “”
echo “now ending script and quitting terminal”
sleep 3
killall Terminal
exit 0
March 12, 2009 at 1:47 pm
The scutil syntax should be:
/usr/sbin/scutil –-set ComputerName “OSX_Standard_Image”
/usr/sbin/scutil –-set LocalHostName “ OSX_Standard_Image”
You might also want to set:
/usr/sbin/scutil –-set HostName “ OSX_Standard_Image”
You might also want to delete:
/bin/rm “/System/Library/Extensions.kextcache”
March 12, 2009 at 2:05 pm
Gil:
You’re right about the scutil syntax, and that’s what’s in the source of this article, but WordPress seemed to have munged it up on display. I added some different formatting tags and now it looks right!
I don’t set the HostName, as that is set automatically via DNS in our environment on first boot, so setting it in the image is pointless (for us).
Unless you change the kernel extensions in your image _after_ you create your image there should be no need to delete the Extensions.kextcache, since the cache will reflect the current set of kernel extensions. Deleting it shouldn’t hurt anything, but will make the initial startup after imaging take longer.