Skip to main content

Mac OS X "SOE" Day 5

Page Redirection > continued from day 4...

Continuing on from the "build" phase setup we need to script our "firstboot" options. The last step in the build phase set our "firstboot" script as "/var/root/firstboot.sh".

So what's the minimum we need in the "firstboot" phase? There isn't really a minimum for this phase as you can do most of this stuff at localisation phase. The main things I do here relate to writing prefs that a machine specific ie, contain UUID or MACADDRESS
  • Setting default screensaver
  • Setting default menu extras
  • Run Apple Software updates that require a booted OS
  • Set the initial HOSTNAME, LOCALHOSTNAME and COMPUTERNAME
  • Set the initial Energy Saver settings
  • Disable some Network Services (firewire, bluetooth)
  • Set the initial Network Services Order
  • Disable IPv6

Couple things you will need to know for this stage, how to get the UUID and/or the MACADDRESS. Post 2010 macs seem to use the UUID instead of the MACADDRESS but if you manage multiple models and locations there is no harm in writing two sets of PLISTS (as I do,cuz I'm lazy). Also note these scripts require plistbuddy as the plists are nested and complicated.
# Apple unique workstation UUID.
UUID=$(/usr/sbin/ioreg -rd1 -c IOPlatformExpertDevice | /usr/bin/perl -ne 'if (m/^.*\"IOPlatformUUID\" = \"(.*).*\"$/im) {print $1}')

# Mac address.
MACADDRESS=$(/usr/sbin/networksetup -getMACADDRESS en0 | /usr/bin/awk '{print $3}' | /usr/bin/sed s/://g)


Write the default screensaver prefs.
#* Default preferences.
#+ Modifies /System/Library/User Template
#+ Replacing ${YOURSAVERHERE}
for USER_TEMPLATE in `sudo ls /System/Library/User\ Template`
do
 if [ -r "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences" ]; then
  /bin/echo "Modifying /System/Library/User Template/${USER_TEMPLATE}/Library/Preferences"
  # com.apple.screensaver.plist
  sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.screensaver" askForPassword -int 1
  sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.screensaver" askForPasswordDelay -int 5
  # com.apple.screensaver.UUID.plist
  sudo ${PLISTB} -c 'Add :CleanExit string YES' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${UUID}.plist"
  sudo ${PLISTB} -c 'Add :idleTime integer 900' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${UUID}.plist"
  sudo ${PLISTB} -c 'Add :moduleDict dict' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${UUID}.plist"
  sudo ${PLISTB} -c 'Add :moduleDict:iLifeMediaGroupType integer 0' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${UUID}.plist"
  sudo ${PLISTB} -c 'Add :moduleDict:moduleName string ${YOURSAVERHERE}' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${UUID}.plist"
  sudo ${PLISTB} -c 'Add :moduleDict:path string /Library/Screen\ Savers/${YOURSAVERHERE}.slideSaver' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${UUID}.plist"
  sudo ${PLISTB} -c 'Add :moduleDict:type integer 4' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${UUID}.plist"
  # com.apple.screensaver.MACADDRESS.plist
  sudo ${PLISTB} -c 'Add :CleanExit string YES' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${MACADDRESS}.plist"
  sudo ${PLISTB} -c 'Add :idleTime integer 900' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${MACADDRESS}.plist"
  sudo ${PLISTB} -c 'Add :moduleDict dict' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${MACADDRESS}.plist"
  sudo ${PLISTB} -c 'Add :moduleDict:iLifeMediaGroupType integer 0' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${MACADDRESS}.plist"
  sudo ${PLISTB} -c 'Add :moduleDict:moduleName string ${YOURSAVERHERE}' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${MACADDRESS}.plist"
  sudo ${PLISTB} -c 'Add :moduleDict:path string /Library/Screen\ Savers/${YOURSAVERHERE}.slideSaver' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${MACADDRESS}.plist"
  sudo ${PLISTB} -c 'Add :moduleDict:type integer 4' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${MACADDRESS}.plist"
 fi
done


Write the default menu extras prefs. (might as well have one User Template loop but I'm splitting here for easier reading)
#* Default preferences.
#+ Modifies /System/Library/User Template
for USER_TEMPLATE in `sudo ls /System/Library/User\ Template`
do
 if [ -r "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences" ]; then
  /bin/echo "Modifying /System/Library/User Template/${USER_TEMPLATE}/Library/Preferences"
# com.apple.systemuiserver.plist
  sudo ${PLISTB} -c 'Add menuExtras array' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systemuiserver.plist" 
  sudo ${PLISTB} -c 'Add menuExtras:0 string /Applications/Utilities/Keychain\ Access.app/Contents/Resources/Keychain.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systemuiserver.plist"
  sudo ${PLISTB} -c 'Add menuExtras:1 string /System/Library/CoreServices/Menu\ Extras/Bluetooth.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systemuiserver.plist"
  sudo ${PLISTB} -c 'Add menuExtras:2 string /System/Library/CoreServices/Menu\ Extras/TextInput.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systemuiserver.plist"
  sudo ${PLISTB} -c 'Add menuExtras:3 string /System/Library/CoreServices/Menu\ Extras/Volume.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systemuiserver.plist"
  sudo ${PLISTB} -c 'Add menuExtras:4 string /System/Library/CoreServices/Menu\ Extras/Displays.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systemuiserver.plist"
  sudo ${PLISTB} -c 'Add menuExtras:5 string /System/Library/CoreServices/Menu\ Extras/RemoteDesktop.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systemuiserver.plist"
  # com.apple.systemuiserver.${UUID}.plist (do not load)
  sudo ${PLISTB} -c 'Add dontAutoLoad array' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${UUID}.plist" 
  sudo ${PLISTB} -c 'Add dontAutoLoad:0 string /System/Library/CoreServices/Menu\ Extras/AirPort.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${UUID}.plist"
  sudo ${PLISTB} -c 'Add dontAutoLoad:1 string /System/Library/CoreServices/Menu\ Extras/VPN.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${UUID}.plist"
  sudo ${PLISTB} -c 'Add dontAutoLoad:2 string /System/Library/CoreServices/Menu\ Extras/TimeMachine.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${UUID}.plist"
  sudo ${PLISTB} -c 'Add dontAutoLoad:3 string /System/Library/CoreServices/Menu\ Extras/Battery.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${UUID}.plist"
  # com.apple.systemuiserver.${MACADDRESS}.plist (do not load)
  sudo ${PLISTB} -c 'Add dontAutoLoad array' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${MACADDRESS}.plist" 
  sudo ${PLISTB} -c 'Add dontAutoLoad:0 string /System/Library/CoreServices/Menu\ Extras/AirPort.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${MACADDRESS}.plist"
  sudo ${PLISTB} -c 'Add dontAutoLoad:1 string /System/Library/CoreServices/Menu\ Extras/VPN.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${MACADDRESS}.plist"
  sudo ${PLISTB} -c 'Add dontAutoLoad:2 string /System/Library/CoreServices/Menu\ Extras/TimeMachine.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${MACADDRESS}.plist"
  sudo ${PLISTB} -c 'Add dontAutoLoad:3 string /System/Library/CoreServices/Menu\ Extras/Battery.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${MACADDRESS}.plist"
fi
done


One thing I like to do is add different menu extras for laptop users too (such as giving them the built-in vpn menu).
# Run if a laptop
ioreg -rd1 -c IOPlatformExpertDevice | grep -E model | awk '{print $3}' | sed s/\<\"// | sed s/\"\>// | grep iMac
if [ "$?" == "1" ]; then
# Modify User Template preference defaults
for USER_TEMPLATE in `sudo ls /System/Library/User\ Template`
do
 if [ -r "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences" ]; then
  /bin/echo "Modifying /System/Library/User Template/${USER_TEMPLATE}/Library/Preferences"
  # com.apple.systemuiserver.plist
  sudo ${PLISTB} -c 'Delete menuExtras' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systemuiserver.plist" 
  sudo ${PLISTB} -c 'Add menuExtras array' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systemuiserver.plist" 
  sudo ${PLISTB} -c 'Add menuExtras:0 string /Applications/Utilities/Keychain\ Access.app/Contents/Resources/Keychain.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systemuiserver.plist"
  sudo ${PLISTB} -c 'Add menuExtras:1 string /System/Library/CoreServices/Menu\ Extras/AirPort.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systemuiserver.plist"
  sudo ${PLISTB} -c 'Add menuExtras:2 string /System/Library/CoreServices/Menu\ Extras/VPN.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systemuiserver.plist"
  sudo ${PLISTB} -c 'Add menuExtras:3 string /System/Library/CoreServices/Menu\ Extras/Bluetooth.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systemuiserver.plist"
  sudo ${PLISTB} -c 'Add menuExtras:4 string /System/Library/CoreServices/Menu\ Extras/TextInput.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systemuiserver.plist"
  sudo ${PLISTB} -c 'Add menuExtras:5 string /System/Library/CoreServices/Menu\ Extras/Volume.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systemuiserver.plist"
  sudo ${PLISTB} -c 'Add menuExtras:6 string /System/Library/CoreServices/Menu\ Extras/Displays.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systemuiserver.plist"
  sudo ${PLISTB} -c 'Add menuExtras:7 string /System/Library/CoreServices/Menu\ Extras/RemoteDesktop.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systemuiserver.plist"
  sudo ${PLISTB} -c 'Add menuExtras:8 string /System/Library/CoreServices/Menu\ Extras/Battery.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systemuiserver.plist"
  # Ensure ByHost is there
  sudo /bin/mkdir -p "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost"
  # com.apple.systemuiserver.${UUID}.plist (do not load)
  sudo ${PLISTB} -c 'Delete dontAutoLoad' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${UUID}.plist" 
  sudo ${PLISTB} -c 'Add dontAutoLoad array' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${UUID}.plist" 
  sudo ${PLISTB} -c 'Add dontAutoLoad:0 string /System/Library/CoreServices/Menu\ Extras/TimeMachine.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${UUID}.plist"
  # com.apple.systemuiserver.${MACADDRESS}.plist (do not load)
  sudo ${PLISTB} -c 'Delete dontAutoLoad' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${MACADDRESS}.plist" 
  sudo ${PLISTB} -c 'Add dontAutoLoad array' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${MACADDRESS}.plist" 
  sudo ${PLISTB} -c 'Add dontAutoLoad:0 string /System/Library/CoreServices/Menu\ Extras/TimeMachine.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${MACADDRESS}.plist"
 fi


You may also want these same prefs copied to your local admin users that have already been created. I'll let you decide how you want to do it.
# com.apple.screensaver.plist
sudo /bin/cp -f /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.screensaver.plist /var/${SHORTNAME}/Library/Preferences/
# com.apple.screensaver.UUID.plist
sudo /bin/cp -f /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${UUID}.plist /var/${SHORTNAME}/Library/Preferences/ByHost/
# com.apple.screensaver.MACADDRESS.plist
sudo /bin/cp -f /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${MACADDRESS}.plist /var/${SHORTNAME}/Library/Preferences/ByHost/
#+ Set menu extras
sudo /bin/cp -f /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systemuiserver.plist /var/${SHORTNAME}/Library/Preferences/
sudo /bin/cp -f /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${UUID}.plist /var/${SHORTNAME}/Library/Preferences/ByHost/
sudo /bin/cp -f /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${MACADDRESS}.plist /var/${SHORTNAME}/Library/Preferences/ByHost/


Set the initial hostname. I set it to a combination of the SERIALNUMBER and MACADDRESS. I do this so the machine is easily identifiable via Apple Remote Desktop. I can't always be onsite when a mac is imaged.
# Serial number.
SERIAL=$(/usr/sbin/ioreg -c IOPlatformExpertDevice | /usr/bin/sed -E -n -e '/IOPlatformSerialNumber/{s/^.*[[:space:]]"IOPlatformSerialNumber" = "(.+)"$/\1/p;q;}')

# Mac address.
MACADDRESS=$(/usr/sbin/networksetup -getMACADDRESS en0 | /usr/bin/awk '{print $3}' | /usr/bin/sed s/://g)

#* Set Computer name,Local Host Name, Hostname, Netbios name.
sudo /usr/sbin/scutil --set ComputerName "${SERIAL}-${MACADDRESS}"
sudo /usr/sbin/scutil --set LocalHostName "${SERIAL}-${MACADDRESS}"
sudo /usr/sbin/scutil --set HostName "${SERIAL}-${MACADDRESS}"
sudo /bin/hostname "${SERIAL}-${MACADDRESS}"
sudo /usr/bin/defaults write /Library/Preferences/SystemConfiguration/com.apple.smb.server NetBIOSName "${SERIAL}-${MACADDRESS}"


Set the initial energy saver preferences.
#* Set Computer sleep idle time, Display sleep idle time, Disable hard disk sleep.
sudo /usr/sbin/systemsetup -setcomputersleep "60"
sudo /usr/sbin/systemsetup -setdisplaysleep "15"
sudo /usr/sbin/systemsetup -setharddisksleep off


Disable IPv6. I've had AD binding bugs (so have others I've read in posts on the net. Plus I don't use it yet).
#* Disable ipv6.
sudo /usr/sbin/networksetup -setv6off "Airport"
sudo /usr/sbin/networksetup -setv6off "Bluetooth Dun"
sudo /usr/sbin/networksetup -setv6off "Bluetooth Pan"
sudo /usr/sbin/networksetup -setv6off "Ethernet"
sudo /usr/sbin/networksetup -setv6off "FireWire"
sudo /usr/sbin/networksetup -setv6off "Wi-Fi"


Order your networks services for priority.
#* Order Services.
sudo /usr/sbin/networksetup -ordernetworkservices "Ethernet" "Wi-Fi" "FireWire"
sudo /usr/sbin/networksetup -ordernetworkservices "Ethernet" "Wi-Fi" "FireWire" "Bluetooth DUN"
sudo /usr/sbin/networksetup -ordernetworkservices "Ethernet" "Wi-Fi" "FireWire" "Bluetooth DUN" "Bluetooth PAN"
sudo /usr/sbin/networksetup -ordernetworkservices "Ethernet" "Airport" "FireWire"
sudo /usr/sbin/networksetup -ordernetworkservices "Ethernet" "Airport" "FireWire" "Bluetooth DUN"
sudo /usr/sbin/networksetup -ordernetworkservices "Ethernet" "Airport" "FireWire" "Bluetooth DUN" "Bluetooth PAN"


Once you are done with your "firstboot" phase don't forget to remove it ;)

Disable the firstboot loginhook.
#* Disable firstboot LoginHook
sudo /usr/bin/defaults delete "/var/root/Library/Preferences/com.apple.loginwindow" LoginHook


That's all I can think of for now ;) maybe a post implementation review to cover changes later on.... stay tuned for the "localisation" phase.

Popular posts from this blog

Mac OS X "SOE" Day 7

Page Redirection > continued from day 6... In summary, here is my method for creating a Mac OS X 10.7.3 Standard Operating Environment "SOE" Image. Overview The goal is to create a "MASTER" non-booted SOE that can be used with multiple models and it multiple sites with different local requirements. My intention is to use this "MASTER" image in a manual restore procedure due to the fact netboot facilities cannot be made available to all the sites I support however the DMG files are netboot compatible. Requirements Lion Recovery Disk Assistant v1.0 "TARGET" workstation. A compatible workstation that will be used to install Mac OS X 10.7.3 and capture a DMG image(s). "ADMIN" workstation. A workstation with Disk Utility that you will use to capture your DMG image(s). External storage such as a USB HARD DISK. Setup Downloaded the Lion Recovery Disk Assi

Mac OS X "SOE" Day 6

Page Redirection > continued from day 5... Continuing on from the "firstboot" phase setup we need to script our "localiser" options. I previously set my build phase to autologin and run the firstboot script, the localiser phase essentially sits there and waits for you to run it. In my case I have an applescript GUI wrapper that requests some info to use in the localisation. I request a TAG number which is an organisational internal number and I also request a user name that will be set as the OWNER. NOTE : I ordered these specifically...not just because it makes sense logically but also technically. For example, setting the Language actually zaps a plist file (.GlobalPreferences) which you need to write to for Locale and Country info. This stuff is going to be totally dependant on your environment, as an example here is what I do. So what's the minimum we need in the "localiser" phase? Depends on how many sites you support,