Skip to main content

Mac OS X "SOE" Day 3

Page Redirection > continued from day 2...

Ready to copy my scripts over, as previously mentioned I am thinking of having 3 phases;
  1. build - preps the image for dmg capture.
  2. firstboot - runs anything I can't do in build ie, writing to byhost files etc that require UUID or Macaddress. Basically machine/model specific settings.
  3. localise - runs localisation scripts such as language, locale etc etc. Basically a set of dynamic scripts in case you are an admin for multiple offices, multiple countries.

So what's the minimum we need in the "build" phase?
  1. Disable the Setup Wizard.
  2. Disable the Registration Wizard.
  3. Create a local admin user(s) and set autologin for the firstboot phase.
  4. Enable root (set the password).
  5. Enable SSH Access
  6. Enable VNC Access
  7. Enable ARD Access
  8. Disable softwareupdate automatic updates "schedule"
  9. Cleanup/Minimise the dmg where possible.
  10. Set a firstboot loginhook for the second phase.

What are some other nice things you may want? (I'm doing the following)
  1. Enable Access for Assistive Devices (maybe some stuff can't be script nicely so use Applescript instead).
  2. Modify default prefs in /System/Library/User Templates (you may want to do this prior to creating your local admin users so they get the defaults too...)
  3. Add a link to often used Directory Utility.
  4. Add a link to often used Printer Utility.

Now lets begin, starting from the previous step (booted in single user mode) run these. (I'll leave it up to you how you want to package them, I like to keep things non-proprietary so I don't roll them into PKG files, instead keep them as shell scripts).

Mount the disk first so you can make changes to the filesystem.
/sbin/mount -uw /

Disable Setup Wizard
sudo /usr/bin/touch "/private/var/db/.AppleSetupDone"
sudo /usr/sbin/chown root:wheel "/private/var/db/.AppleSetupDone"

Disable Registration Wizard
sudo /usr/bin/touch "/Library/Receipts/.SetupRegComplete"
sudo /usr/sbin/chown root:wheel "/Library/Receipts/.SetupRegComplete"

Create a local admin user account (run this as many times as you need if you want more than one). I am doing it via single user but you could use InstaDMG's CreateLionUser pkg file to target a booted volume. I just prefer this way as I know exactly whats happening and don't have to worry about bugs.
# For 10.7 load open directory
launchctl load /System/Library/LaunchDaemons/com.apple.opendirectoryd.plist

# Create a user (replacing the SHORTNAME and PASSWORD vars)
# NOTE : I redirect NFSHomeDirectory to /var so local admins are less visible to end users.
# NOTE : UniqueID less than 500
sudo /usr/bin/dscl . -create /Users/${SHORTNAME}
sudo /usr/bin/dscl . -create /Users/${SHORTNAME} UserShell /bin/bash
sudo /usr/bin/dscl . -create /Users/${SHORTNAME} RealName "${SHORTNAME}"
sudo /usr/bin/dscl . -create /Users/${SHORTNAME} UniqueID 444
sudo /usr/bin/dscl . -create /Users/${SHORTNAME} PrimaryGroupID 80
sudo /usr/bin/dscl . -create /Users/${SHORTNAME} NFSHomeDirectory "/var/${SHORTNAME}"
sudo /usr/bin/dscl . -passwd /Users/${SHORTNAME} "${PASSWORD}"
sudo /usr/bin/dscl . -append /Groups/admin GroupMembership ${SHORTNAME}
sudo /bin/cp -Rfv /System/Library/User\ Template/English.lproj "/var/${SHORTNAME}"
sudo /usr/sbin/chown -R ${SHORTNAME}:admin "/var/${SHORTNAME}"

# Hide the user from the loginwindow
sudo defaults write /Library/Preferences/com.apple.loginwindow HiddenUsersList -array-add "${SHORTNAME}"

# Hide the < UniqueID 500 users.
sudo defaults write /Library/Preferences/com.apple.loginwindow Hide500Users -bool TRUE

# Prevent "Other" from appearing in the loginwindow.
sudo defaults write /Library/Preferences/com.apple.loginwindow SHOWOTHERUSERS_MANAGED -bool FALSE

# Enable autoLoginUser for this user.
sudo /usr/bin/defaults write "/Library/Preferences/com.apple.loginwindow" autoLoginUser -string "${SHORTNAME}"

# Set autologin password
# NOTE : Can't script this :( just manually create a user and generate one then deliver it via paylaod.
sudo /bin/cp -Rfv kcpassword" "/etc/kcpassword"
sudo /bin/rm -Rf "/etc/kcpassword.disabled"

# Note the special permissions for kcpassword.
sudo /usr/sbin/chown root:wheel "/etc/kcpassword"
sudo /bin/chmod 600 "/etc/kcpassword"

Enable root by simply setting the password.
passwd

Enable ssh for remote support.
# Enable the daemon.
sudo /usr/bin/defaults delete "/System/Library/LaunchDaemons/ssh" "Disabled"

# Note the special permissions for LaunchDaemons.
sudo /usr/sbin/chown root:wheel "/System/Library/LaunchDaemons/ssh.plist"
sudo /bin/chmod 644 "/System/Library/LaunchDaemons/ssh.plist"

# MOTD banner.
sudo /bin/echo "Unauthorized access to these resources is prohibited." > "/etc/motd"

# Note the special permissions for motdsudo /bin/chmod 755 "/etc/motd"
sudo /usr/sbin/chown root:wheel "/etc/motd"

Set a VNC password then enable VNC.
# Set encrypted VNC password string (replacing the PASSWORD var)
ENCVNCPASSWD=$(echo "${PASSWORD}" | perl -we 'BEGIN { @k = unpack "C*", pack "H*", "1734516E8BA8C5E2FF1C39567390ADCA"}; $_ = <>; chomp; s/^(.{8}).*/$1/; @p = unpack "C*", $_; foreach (@k) { printf "%02X", $_ ^ (shift @p || 0) }; print "\n"')
sudo /bin/echo "${ENCVNCPASSWD}" > "/Library/Preferences/com.apple.VNCSettings.txt"

# com.apple.VNCSettings.txt special permissions.
sudo /usr/sbin/chown -R root:wheel "/Library/Preferences/com.apple.VNCSettings.txt"
sudo /bin/chmod -R 600 "/Library/Preferences/com.apple.VNCSettings.txt"

# Enable VNC
/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -activate -access -on -clientopts -setvnclegacy -vnclegacy yes -restart -agent

Enable ARD.
# Enable ARD with options. Up to you what options you want. Consult MAN.
/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -activate -configure -access -on -users ${SHORTNAME} -privs -all -clientopts -setvnclegacy -vnclegacy yes

Disable softwareupdate "scheduled" updates using a LaunchDaemon. I am using a launch daemon as the plist file is a little awkward to deal with using the defaults command.
# Disable softwareupdate schedule via a daemon
sudo /usr/bin/defaults write /Library/LaunchDaemons/org.softwareupdate Label org.softwareupdate
sudo /usr/bin/defaults write /Library/LaunchDaemons/org.softwareupdate LaunchOnlyOnce -bool TRUE
sudo /usr/bin/defaults write /Library/LaunchDaemons/org.softwareupdate Program "/usr/sbin/softwareupdate"
sudo /usr/bin/defaults write /Library/LaunchDaemons/org.softwareupdate RunAtLoad -bool TRUE
sudo /usr/bin/defaults write /Library/LaunchDaemons/org.softwareupdate ProgramArguments -array "/usr/sbin/softwareupdate" "--schedule" "off"

# Note the special permissions for LaunchDaemons.
sudo /usr/sbin/chown root:wheel "/Library/LaunchDaemons/org.softwareupdate.plist"sudo /bin/chmod 644 "/Library/LaunchDaemons/org.softwareupdate.plist"

Cleanup and minimise.
# Remove Alex Voice and save 450mb in DMG size, I've tried it in 10.5 and 10.6 and never had a problem.
sudo /bin/rm -Rf "/System/Library/Speech/Voices/Alex.SpeechVoice"

# Remove the sleepimage
# NOTE : You can disable this completely by running "pmset -a hibernatemode 0" if you know what your are doing ;)
sudo /bin/rm -Rf "/private/var/vm/sleepimage"

# Remove caches and swap just-in-case they exist
sudo /bin/rm -Rf "/private/var/vm/swapfile0"
sudo /bin/rm -Rf ~/Library/Caches/*
sudo /bin/rm -Rf /Library/Caches/*
sudo /bin/rm -Rf /System/Library/Caches/*

Setup firstboot loginhook
# Create a loginhook to run scripts that cannot be added to the build. ie, scripts that write byhost info.
sudo /usr/bin/defaults write "/var/root/Library/Preferences/com.apple.loginwindow" LoginHook -string "/var/root/firstboot.sh"

Stay tuned...

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.

RequirementsLion 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. SetupDownloaded the Lion Recovery Disk Assistant v1.0 and followed the instructions to setup an external Recovery D…

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, I support over 50 si…

Portable TextWrangler (kinda)

Terminal is great, but sometimes I'm too lazy to use vi and editing lots of shell scripts is waaaayyyyy more efficient with TextWrangler. I use this small dropbox hack so I can sync my stationery and settings across multiple macs. #!/bin/bash #+ Portable TextWrangler #* Formatted date & time string. FORMATTED_DATE=`/bin/date "+%Y-%m-%d%H%M%S"` #+ Remove it from /Applications (optional, just so you can replace it with a ln to your dropbox) sudo /bin/mv -f /Applications/TextWrangler.app ~/.Trash/ #* Add a link in /Applications to your DropBox copy sudo /bin/ln -Fs ~/DropBox/TextWrangler.app /Applications/TextWrangler.app #* Archive existing folder /bin/mv -f ~/Library/Application\ Support/TextWrangler{,.$FORMATTED_DATE} #+ Create cloud app support folder /bin/mkdir -p ~/DropBox/TextWrangler #+ Link cloud app support folder to your local workstation (this contains your stationery etc etc) sudo /bin/ln -Fs ~/DropBox/TextWrangler ~/Library/Application\ Support/TextWra…