Home » Archive for category 'Tech'

Tech Archive

CLI image conversion JPG to PNG

Posted 2014/08/16 By mikep345678

Using ImageMagick (on Linux) to convert all jpgs in a folder to png, with alpha layer, with longest side 400 pixels:

for f in *.jpg; do convert -verbose -resize "400x400>" -alpha on "$f" "${f/%jpg/png}"; done

 

Mac OS X Disk Images

Posted 2013/10/10 By mikep345678

Create sparsebundle:
hdiutil create -size $SIZE -fs HFS+J -Volname $VOLNAME -type SPARSEBUNDLE $VOLNAME_backup

Convert to compressed sparsebundle:
hdiutil convert $VOLNAME_backup.sparsebundle -format UDBZ -o $VOLNAME_backup_compressed.sparsebundle.dmg

Mount read-only sparsebundle with read-write Shadow:
hdiutil attach -owners on $VOLNAME_backup_compressed.sparsebundle.dmg -mount required -shadow

Unmount:
hdiutil detach $VOLNAME

Commit changes in Shadow (can’t be done in-place; have to create new file):
hdiutil convert -format UDBZ -o $VOLNAME_backup_compressed_merged.sparsebundle.dmg $VOLNAME_backup_compressed.sparsebundle.dmg -shadow

Michael Battista
(originally from http://www.ccs.neu.edu/home/battista/articles/winbind/winbind.pdf)

1. Introduction

I recently was assigned the task of joining a Debian workstation to a Windows Server 2003 Active Directory domain. Though most of the documentation I read for doing this was rather straightforward, 100% of that documentation turned out to be only 85% useful. While all were easy to follow, at the end of the day I found myself piecing together bits of information from all different sources. Only after deciphering cryptic log messages, consulting my colleagues, and experimenting did I finally have this working. Here I try to provide a complete walkthrough of this procedure, paying close attention to the often overlooked details I encountered in my trials.

The procedure described in this article was performed on a Debian-based system using a Windows Server 2003 domain controller (PDC). Therefore, some of the details in this article (package names, file locations, commands) mentioned here may be inconsistent with those of your distribution. Consult your system’s documentation for these details.

2. Install the Software

You will need to install packages for MIT Kerberos, Samba, Winbind, and NTP. The following command should suffice:[1]

sudo apt-get install libkrb53 krb5-config samba winbind ntpdate ntp-server

Just accept the default settings during package installation. We will be configuring these services later.

3. Stop the Services

To avoid unnecessary complications, stop the Samba, Winbind, and NTP services.

sudo /etc/init.d/samba stop
sudo /etc/init.d/winbind stop
sudo /etc/init.d/ntp-server stop

4. Configure Kerberos

Active Directory uses the Kerberos protocol for service requests. To configure your workstation as a Kerberos client, you will need to modify /etc/krb5.conf.

The first thing you will need to configure is the Kerberos realm of your domain. For all intensive purposes, this merely means pointing the Kerberos libraries to your primary domain controller. In /etc/krb5.conf, there will be a section named [realms]. Add a subsection like the following:[2]

REALMNAME {
kdc = pdc_ip_address
}

in all uppercase. If your domain name is AD.domain, for instance, you would replace REALMNAME above with AD.DOMAIN.

pdc_ip_address is the IP address of your primary domain controller. Heed this warning from Samba-3 By Example (http://www.samba.org/samba/docs/man/Samba-Guide/DomApps.html#id2585260):

Kerberos needs to be able to do a reverse DNS lookup on the IP address of your KDC. Also, the name that this reverse lookup maps to must either be the NetBIOS name of the KDC (i.e., the hostname with no domain attached) or the NetBIOS name followed by the realm. If all else fails, you can add a /etc/hosts entry mapping the IP address of your KDC to its NetBIOS name. If Kerberos cannot do this reverse lookup, you will get a local error when you try to join the realm.

If the output of host pdc_ip_address does not contain the correct DNS name, reconfigure hostname resolution before moving on.

With your realm in place, navigate to the [libdefaults] section in the same file and set the default Kerberos realm to REALMNAME:

[libdefaults]
default_realm = REALMNAME

5. Configure NTP

The Kerberos protocol relies heavily on timestamps. If the clock on the Debian workstation is out of sync with the primary domain controller, things will break. Windows Server 2003 by default broadcasts its time via the Network Time Protocol (NTP). To synchronize your clock with the primary domain controller, try the following:[3]

sudo ntpdate pdc_ip_address

If you receive an “NTP socket in use” error, you need to stop the NTP daemon (sudo /etc/init.d/ntp-server stop) and try again. If ntpdate still fails, chances are that either the Windows Time Service is not running or one or more firewalls between the workstation and the domain controller are blocking port 123/UDP. Start the service and/or create exceptions for this port and try again.

When successful, ntpdate synchronizes your clock enough to start the NTP daemon, which handles all further synchronization. To point this daemon at the Windows domain controller, locate the first uncommented line in /etc/ntp.conf beginning with server and make the following change:

server pdc_ip_address

With this setting in place, restart the NTP daemon:

sudo /etc/init.d/ntp-server start

To confirm that your workstation is contacting the primary domain controller for time updates, run ntpq -p. If everything is configured correctly, you should see your primary domain controller’s IP address or DNS name in the list of time servers.

6. Configure Winbind

The Winbind service is the engine of this operation. It handles all communication with the Active Directory domain controller and manages the Windows-to-Unix translations that must occur.

You configure this service in /etc/samba/smb.conf. The following lines should be added to its global section:

realm = REALMNAME
workgroup = DOMAINNAME
security = ads
idmap uid = 10000-20000
idmap gid = 10000-20000
template shell = /bin/bash
template homedir = /home/%D/%U
winbind use default domain = yes

Replace REALMNAME with the name of the Kerberos realm you configured in the previous section. DOMAINNAME is the shortened version of the domain name. The idmap lines list the range of ID’s that Winbind will use when translating Windows users and groups to Unix.

Template shell and template homedir list the user’s login shell and home directory. The %D translates to the workgroup (DOMAINNAME) while the %U translates to the current user. Of course, you could leave out the %D and choose a more traditional location, such as /home/%U, if you wish. Just make sure that the parent directory of your Winbind home directories (in our case /home/%D) exists before attempting to login as a Windows user.[4]

The winbind use default domain option modifies the representation of Windows usernames. By default, Windows users must login by prefixing their username with workgroup followed by a ’\’ (DOMAINNAME\battista). As a convenience for users, you can set winbind use default domain to yes so that they no longer need to include this prefix. Just be wary of conflicts with existing local accounts.

7. Configure Nsswitch

Your system uses /etc/nsswitch.conf to determine where it should look to resolve various types of lookups. To resolve users and groups from Active Directory, add a reference to the Winbind name service module in the passwd and group lines. Below is the relevant portion of /etc/nsswitch.conf:

passwd:
files winbind
group:
files winbind

The order in which these modules are listed reflects the order in which they will be used. With the above configuration, our system will first query files on the local drive (/etc/passwd and /etc/group) before querying Active Directory. Other modules, such as nis or ldap, may be listed in this file. Just make sure that you add the appropriate winbind entries to passwd and group. To activate these changes run the following command:

sudo ldconfig

This registers the winbind module with the system so that resolution can take place.

8. Join the Domain

With Kerberos and Winbind configured, you’re now ready to join your Debian workstation to the Windows Active Directory domain.

Before you do, check the hostname of your Debian workstation. Due to restrictions in the NetBIOS protocol, the hostname must contain no more than 15 characters. If you see a STATUS_BUFFER_OVERFLOW message in the winbind log, odds are the hostname is invalid. Now would also be a good time to clear whatever cache files, if any, Winbind had previously generated. The Winbind cache is located in /var/lib/samba/. Backup this directory to /var/lib/samba.bak/ and delete all the files in the original.

With these housekeeping items taken care of, try joining the domain:[5]

sudo net ads join -U "DOMAINADMIN"

Replace DOMAINADMIN with the name of a user that has privileges to add computers to the domain. If all goes well, you should receive a short message stating that you have successfully joined the domain[6]. If this step fails, chances are that a firewall is restricting access to one or more of the following ports: 88/TCP, 88/UDP, 389/TCP, 464/UDP. Create exceptions for these ports and try again.

9. Start the Services

Now that our workstation is joined to the domain, restart the Samba and Winbind services.

sudo /etc/init.d/samba start

sudo /etc/init.d/winbind start

10. Check Name Resolution

At this point, you should be able to resolve users and groups from the Windows Active Directory domain using getent passwd and getent group. If these commands don’t display your Windows accounts, try to resolve them using wbinfo -u and wbinfo -g. These commands query the Winbind service directly, bypassing the name service switch. If you can resolve users and groups withwbinfo, go back and make sure you configured /etc/nsswitch.conf properly.

If resolution still fails, check if nscd is running. According to the Samba-3 Howto, “if nscd is running on the UNIX/Linux system, then even though NSSWITCH is correctly configured, it will not be possible to resolve domain users and groups for file and directory controls.” Stop this service and retry the steps mentioned above. If nscd is not running, and you are still having problems with resolution, make sure that ports 139/TCP and 445/TCP on the primary domain controller are not blocked by a firewall. Once your workstation is joined to the domain, Winbind uses these ports to perform its lookups.

Also, look out for the following situation. getent passwd lists all of the Active Directory accounts, but getent passwd user fails. Running id user also fails for Active Directory users. If you run into this problem, make sure that the hostname of the workstation you are configuring is unique within the Active Directory domain. If /var/log/samba/log.nmbd reports that nmbd was unable to register the hostname, choose a unique hostname for your workstation and rejoin the domain.

11. Configure PAM

Name resolution is great, but in order to use the Windows accounts for authentication, you need to configure PAM. The Pluggable Authentication Module subsystem (PAM) provides a layer of abstraction for applications that require authentication. Essentially, an application can authenticate against many different backends without having to know anything about the underlying protocols. A PAM-aware application simply requests authentication and then trusts PAM to retrieve it. This layer of abstraction is achieved via PAM modules.

To allow applications to authenticate against Active Directory, you need to register the pam_winbind module with the PAM system. With winbind properly configured, this module provides the logic necessary to retrieve authentication information from Active Directory. Three files in the PAM configuration directory are of interest to us: /etc/pam.d/common-account, /etc/pam.d/common-auth, and /etc/pam.d/common-session. These files merely represent three different stages in the authentication process. Insert a reference to pam_winbind.so in these files:

# /etc/pam.d/common-account
account sufficient pam_winbind.so
account required pam_unix.so
# /etc/pam.d/common-auth
auth sufficient pam_winbind.so
auth required pam_unix.so use_first_pass
# /etc/pam.d/common-session
session sufficient pam_winbind.so
session required pam_unix.so

Normally, PAM will grant authentication only if all of its modules succeed. By changing the priority of a module from required to sufficient, you instruct PAM to grant authentication as soon as that particular module succeeds. In our configuration, PAM won’t bother to check the local files if the user in question resides in Active Directory. This is the desired behavior.

Notice, too, that we added the use_first_pass parameter to modules following pam_winbind in /etc/pam.d/common-auth. In the event that we are logging in as a local user, PAM will check with Active Directory and fail before moving to the next module. Rather than prompt for another password, we tell the pam_unix module to use the password that was previously entered.

Before we can start using our Active Directory accounts, one last change must be made to our PAM configuration. We need to configure our system to create home directories for each of the Active Directory users. Insert a reference to the pam_mkhomedir module in /etc/pam.d/common-session as shown below:

# /etc/pam.d/common-session
session required pam_mkhomedir.so skel=/etc/skel/ umask=0022
session sufficient pam_winbind.so
session required pam_unix.so

When an Active Directory user logs in to our system for the first time, the pam_mkhomedir module will create his home directory, populate it with files from /etc/skel/, and set file permissions according to the umask 0022. This saves us the hassle of having to create each user’s home directory ourselves. Make sure to set the priority of this module to required, as shown above, to prevent a user from logging in should creation of his home directory fail.

12. Conclusion

With Kerberos, Winbind, Nsswitch, and PAM configured, you should now be able to login and access services on your Debian workstation using your Active Directory accounts. Each Active Directory user will have a local home directory on the Debian system, and you will be able to manage your system as if these users were native Unix accounts.

Though sufficient for a network where users typically use only one workstation, this setup is inadequate for an enterprise environment. By default, the Winbind Windows-to-Unix ID mappings are not kept consistent across client workstations. If you were to export user home directories via NFS, as is common in large networks, you would quickly run into trouble.

A more robust solution, better suited for an enterprise environment, would involve keeping the ID mappings consistent across all workstations and automounting shared home directories at login. My next article will present one way of achieving this.

Regardless of which setup you choose, you are now well on your way to achieving a streamlined, heterogenous network of Windows and Linux workstations.

Notes

1. Note that these package names are Debian-specific. Look for similarly named packages for your particular package management system.

2. To find the name of your domain, open Control Panel -> Administrative Tools -> Active Directory Domains and Trusts on your primary domain controller. Your domain name will be listed in the side panel.

3. The timezone on your Debian workstation must be correct for the synchronization to be effective. If ntpdate is successful, but the time seems ahead or behind, run tzconfig to select the appropriate timezone.

4. If it does not, the system will be unable to create home directories for the Windows users, which will prevent them from logging in.

5. Many of the articles I read about this procedure suggested to run kinit before joining the domain. I found that this step is unnecessary when net ads is specified.

6. This message may be accompanied by Kerberos preauthentication errors. These may be safely ignored.

Unix/Linux/OSX scripting

Posted 2012/08/18 By mikep345678

{stolen from here…}

Unix Shell Stuff
 


 

$# - Contains the number of arguments passed to the 
      program in the form of positional variables.

$* - Contains all the positional parameters passed to 
      the program.

$1-$9 - Positional parameters.

$0 - Contains the program name.

$$ - Contains the process ID of the current process.

$? - Contains the exit status of the last command executed. 

expr - Used to evaluate arguments as mathematical 
        expressions.  ex: CNT=`expr $CNT + 1` 

; - Used to separate commands on command line. 

\ - Used to continue the command on the next line.

\c - Used to suppress newline.
      ex: echo "Enter Name:\c" ; read name

read - Assigns the value entered into the given variable.
         ex: echo "Enter Name:"  
             read name

` ` - A command within grave accent marks returns 
       the output to the variable ex: DATE=`date`.

set - Set the values of the command line argument 
        variables ($1-$9) to it's arguments.

--   - No more options follow.

if expressions:
  if
  then
       Commands
   else
       Commands
  fi

   :     Null Character (always true)

   ;     Separates commands on one line 

   #!    As the first characters in the first line of shell script,
           tells OS that what follows, is the path to the shell to execute this script with.

   exec  Does not start an new process for the command being execed.
            Over lays the current process instead of starting new one.  Does not return control to shell.

   break Exits "for", "while" and "until" loop.

 


 

Testing Character Data:
 

 
   =   Equals, string comparisons ex: if [ "$str1" = "str2" ]; then    (equal)

   !=  Not equal, string comparisons ex: if [ "$str1" != "str2" ]; then    (not equal)

   -n string - True if the length of string is greater than 0 (is not null)

   -z string - True if string is null (has a length of 0)

   test - Test strings ex: test "$str" = "abc"

 


 

Testing Numeric Data:
 

     -eq -  Equals                      ex:  if [ $1 -eq 0 ]; then
     -ne -  Not equal                   ex:  if [ $1 -ne 0 ]; then
     -gt -  Greater than                ex:  if [ $1 -gt 0 ]; then
     -ge -  Greater than of equal to    ex:  if [ $1 -ge 0 ]; then
     -lt -  Less than                   ex:  if [ $1 -lt 0 ]; then
     -le -  Less than or equal to       ex:  if [ $1 -le 0 ]; then


Testing For Files:

     True if
        -r    Read permission           ex:  if [ -r $FILE ]; then
        -w    Write permission          ex:  if [ -w $FILE ]; then
        -x    Execute permission        ex:  if [ -x $FILE ]; then
        -f    Regular file              ex:  if [ -f $FILE ]; then
        -d    Directory                 ex:  if [ -d $FILE ]; then
        -c    Character special file    ex:  if [ -c $FILE ]; then
        -b    Block special file        ex:  if [ -b $FILE ]; then
        -s    File not zero             ex:  if [ -s $FILE ]; then
        -t    Terminal device           ex:  if [ -t $FILE ]; then
        -o    True if either (OR)       ex:  if [ ! -r $FILE  -o ! -f $FILE ]; then
        -a    True if both (AND)        ex:  if [ -r $FILE -a -f $FILE ]; then

lifted directly from http://www.randomsquared.com/post/22875358548

Mac OS X 10.7.4 SOE

In summary, here is my method for creating a Mac OS X 10.7.3 Standard Operating Environment “SOE” Image. Posted it over on my blogger page but leaning toward migrating to tumblr… so here goes.

  • 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
    1. Lion Recovery Disk Assistant v1.0
    2. “TARGET” workstation. A compatible workstation that will be used to install Mac OS X 10.7.3 and capture a DMG image(s).
    3. “ADMIN” workstation. A workstation with Disk Utility that you will use to capture your DMG image(s).
    4. External storage such as a USB HARD DISK.
  • Setup
    1. Downloaded the Lion Recovery Disk Assistant v1.0 and followed the instructions to setup an external Recovery Disk on an externally attached USB disk. Used a Shintaro Hard Drive Docker and multiple disks for convenience when building images.
    2. Booted the “TARGET” workstation from the Recovery Disk and installed Mac OS X 10.7 using a custom install. Depending on your environment it may not make sense to “Install nearby printers” as your LAN may not allow access to other sites so the installer won’t be able to see what other printers are on your network(s) anyway. I deploy specific printer drivers using my software deployment system rather than adding them to my image(s) as I support many sites.
    3. Once the install completed, rebooted the “TARGET” workstation into TARGET DISK mode, mounted it on the “ADMIN” workstation and captured a DMG. Labelled this DMGOSX_10.7_VANILLA.DMG, I can now restore this to a DMG to a disk and skip steps 1-3 when starting new images in the future.

      (If your “TARGET” workstation isn’t capable of booting into TARGET DISK mode you will need to capture your DMG whilst booted from the Recovery Disk. You may need to plugin additional storage such as a USB or FIREWIRE hard disk so you have somewhere to store the DMG image.)

    4. With the “TARGET” workstation still in TARGET DISK mode and mounted on the “ADMIN” workstation, I downloaded the 10.7.3 combo updater to the “ADMIN” workstation and applied it to the “TARGET” workstation. Using a combo updater will allow me to use the DMG image on multiple models and essentially use the image as a “MASTER”.
    5. Once the combo updater install completed, applied Apple specific Software Updates that can target a non-booted volume then I captured another image (I only apply the latest Java update). I labelled the DMG OSX_10.7.3_VANILLA.DMG, I can now restore this to a DMG to a disk and skip steps 1-5 when starting new images in the future.
    6. With the “TARGET” workstation still in TARGET DISK mode and mounted on the “ADMIN” workstation, copied the build.sh script to /var/root/build.sh on the “TARGET” workstation.
    7. With the “TARGET” workstation still in TARGET DISK mode and mounted on the “ADMIN” workstation, copied Apple Software Updates that require a boot volume into /var/root/Updates on the “TARGET” workstation. (I only apply Safari 5.1.5 and iTunes 10.6.1).
    8. Rebooted the “TARGET” workstation into SINGLE USER mode and executed /var/root/build.sh
    9. Rebooted the “TARGET” workstation into TARGET DISK mode, mounted it on the “ADMIN” workstation and captured a DMG. Labelled the DMG OSX_10.7.3_BUILD.DMG, I can now restore this to a DMG to a disk and skip steps 1-9 when starting new images in the future.
    10. With the “TARGET” workstation still in TARGET DISK mode and mounted on the “ADMIN” workstation, copied boot.sh and localise.sh scripts into /var/root on the “TARGET” workstation and captured a DMG. Labelled the DMG OSX_10.7.3_SOEvXXX.DMG, I can now restore this to a DMG to a disk and skip steps 1-10 when starting new images in the future.
  • Scripts
    • build.sh

      #* build.sh
      #+ Phase 1 of 3
      #+ Run this script via single user mode to prep a Mac OS X 10.7.3 install.
      
      #* PLIST BUDDY
      PB="/usr/libexec/PlistBuddy"
      
      #* Mount volume for writing.
      /sbin/mount -uw /
      
      #* Load Open Directory
      launchctl load /System/Library/LaunchDaemons/com.apple.opendirectoryd.plist
      
      #* Avoid Setup Wizard.
      sudo /usr/bin/touch "/private/var/db/.AppleSetupDone"
      sudo /usr/sbin/chown root:wheel "/private/var/db/.AppleSetupDone"
      
      #* Avoid Registration Wizard.
      sudo /usr/bin/touch "/Library/Receipts/.SetupRegComplete"
      sudo /usr/sbin/chown root:wheel "/Library/Receipts/.SetupRegComplete"
      
      #* Default user preferences.
      #+ Modifies /System/Library/User Template
      #+ Note : com.apple.dock.plist, com.apple.LaunchServices.plist and com.apple.sidebarlists.plist are a bit complex and I'm too lazy to write them with plistbuddy so I supply them as payload items instead.
      #+ Be careful with com.apple.sidebarlists.com, make sure to remove the useritems dictionary as its not dynamic. 
      #+ Note : I set these prior to creating my local admin user accounts to that I can test them, you may not want to in case they are buggy.
      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.ATS.plist
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.ATS" ATSAutoActivation -string ATSAutoActivationDisable
        #+ com.apple.desktop.plist
        sudo $PB -c 'Add Background:default:BackgroundColor array' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.desktop.plist" 
        sudo $PB -c 'Add Background:default:BackgroundColor:0 real 0' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.desktop.plist"
        sudo $PB -c 'Add Background:default:BackgroundColor:1 real 0' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.desktop.plist"
        sudo $PB -c 'Add Background:default:BackgroundColor:2 real 0' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.desktop.plist"
        sudo $PB -c 'Add Background:default:DrawBackgroundColor bool true' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.desktop.plist"
        sudo $PB -c 'Add Background:default:ImageFilePath string ${BACKGROUND}' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.desktop.plist"
        #+ com.apple.desktopservices.plist
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.desktopservices" DSDontWriteNetworkStores -bool TRUE
        #+ com.apple.dock.plist (ugly but too complex for defaults or plistbuddy and I'm lazy)
        sudo /bin/cp -f "/var/root/com.apple.dock.plist" "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.dock.plist"
        #+ com.apple.DiskUtility.plist
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.DiskUtility" advanced-image-options -bool YES
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.DiskUtility" DUDebugMenuEnabled -bool YES
        #+ com.apple.finder.plist
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.finder" _FXShowPosixPathInTitle -bool NO
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.finder" FXDefaultSearchScope -string SCcf
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.finder" FXPreferredViewStyle -string Nlsv
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.finder" NewWindowTarget -string PfHm
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.finder" ShowHardDrivesOnDesktop -bool NO
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.finder" ShowMountedServersOnDesktop -bool YES
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.finder" ShowRemovableMediaOnDesktop -bool YES
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.finder" ShowPathbar -bool YES
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.finder" ShowStatusBar -bool YES
        #+ com.apple.FontBook.plist
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.FontBook" FBValidateFontsBeforeInstalling -bool NO
        #+ com.apple.iTunes.plist
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.iTunes" disableCheckForUpdates -bool YES
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.iTunes" disableGeniusSidebar -bool YES
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.iTunes" disableGetAlbumArtwork -bool YES
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.iTunes" disablePing -bool YES
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.iTunes" disablePingSidebar -bool YES
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.iTunes" disablePodcasts -bool YES
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.iTunes" disableRadio -bool YES
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.iTunes" disableSharedMusic -bool YES
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.iTunes" dontAutomaticallySyncIPods -bool YES
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.iTunes" lookForSharedMusic -bool NO
        #+ com.apple.LaunchServices.plist (ugly but too complex for defaults or plistbuddy and I'm lazy)
        sudo /bin/cp -f "/var/root/com.apple.LaunchServices.plist" "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.LaunchServices.plist"
        #+ com.apple.NetworkBrowser.plist
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.NetworkBrowser" BrowseAllInterfaces -bool NO
        #+ come.apple.Preview.plist
        #+ NOTE : Changed my mind, not touching this stuff till I play with some more scenarios.
        #sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.Preview" ApplePersistenceIgnoreState YES
        #+ com.apple.Safari.plist
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.Safari" ApplePersistenceIgnoreState YES
        # or...
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.Safari" NSQuitAlwaysKeepsWindows -int 0
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.Safari" AutoFillFromAddressBook -bool NO
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.Safari" AutoFillMiscellaneousForms -bool NO
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.Safari" AutoFillPasswords -bool NO
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.Safari" IncludeDebugMenu 1
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.Safari" LastDisplayedWelcomePageVersionString -string 4.0
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.Safari" NewWindowBehaviour 0
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.Safari" RestoreSessionAtLaunch -bool NO
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.Safari" WebKitJavaScriptCanOpenWindowsAutomatically -bool YES
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.Safari" ShowStatusBar -bool YES
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.Safari" HomePage "http://intranet.rdigest.com"
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.internetconfigpriv" WWWHomePage "http://intranet.rdigest.com"
        #+ com.apple.SetupAssistant.plist
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.SetupAssistant" DidSeeCloudSetup -bool YES
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.SetupAssistant" GestureMovieSeen none
        #+ com.apple.sidebarlists.plist (ugly but too complex for defaults or plistbuddy and I'm lazy)
        sudo /bin/cp -f "/var/root/com.apple.sidebarlists.plist" "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.sidebarlists.plist"
        #+ com.apple.systempreferences.plist
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systempreferences" HiddenPreferencePanes -array "com.apple.preference.startupdisk" "com.apple.prefs.backup" "com.apple.preferences.softwareupdate" "com.apple.preferences.parentalcontrols" "com.apple.preference.internet" "com.apple.preferences.internetaccounts" "com.apple.preferences.icloud" "com.apple.preferences.sharing" "com.apple.preference.desktopscreeneffect" "com.apple.preference.security" "com.apple.preference.engerysaver"
        #+ com.apple.symbolichotkeys.plist (Disable Dashboard and Mission Control Keys so they are default Fn keys)
        sudo $PB -c "Add :AppleSymbolicHotKeys:32:enabled bool NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Set :AppleSymbolicHotKeys:32:enabled NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Add :AppleSymbolicHotKeys:33:enabled bool NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Set :AppleSymbolicHotKeys:33:enabled NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Add :AppleSymbolicHotKeys:34:enabled bool NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Set :AppleSymbolicHotKeys:34:enabled NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Add :AppleSymbolicHotKeys:35:enabled bool NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Set :AppleSymbolicHotKeys:35:enabled NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Add :AppleSymbolicHotKeys:36:enabled bool NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Set :AppleSymbolicHotKeys:36:enabled NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Add :AppleSymbolicHotKeys:37:enabled bool NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Set :AppleSymbolicHotKeys:37:enabled NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Add :AppleSymbolicHotKeys:52:enabled bool NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Set :AppleSymbolicHotKeys:52:enabled NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Add :AppleSymbolicHotKeys:59:enabled bool NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Set :AppleSymbolicHotKeys:59:enabled NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Add :AppleSymbolicHotKeys:62:enabled bool NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Set :AppleSymbolicHotKeys:62:enabled NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Add :AppleSymbolicHotKeys:63:enabled bool NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Set :AppleSymbolicHotKeys:63:enabled NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Add :AppleSymbolicHotKeys:64:enabled bool NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Set :AppleSymbolicHotKeys:64:enabled NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Add :AppleSymbolicHotKeys:65:enabled bool NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Set :AppleSymbolicHotKeys:65:enabled NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Add :AppleSymbolicHotKeys:73:enabled bool NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        sudo $PB -c "Set :AppleSymbolicHotKeys:73:enabled NO" /System/Library/User\ Template/${USER_TEMPLATE}/Library/Preferences/com.apple.symbolichotkeys.plist
        #+ com.apple.TextEdit.plist
        #+ NOTE : Changed my mind, not touching this stuff yet
        #sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.TextEdit" ApplePersistenceIgnoreState YES
        #sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.TextEdit" NSQuitAlwaysKeepsWindows -int 0
        #+ com.apple.TimeMachine.plist
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.TimeMachine" DoNotOfferNewDisksForBackup -bool YES
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.TimeMachine" AutoBackup -bool NO
        #+ com.apple.universalaccess.plist
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.universalaccess" voiceOverOnOffKey -bool NO
        #+ .GlobalPreferences
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/.GlobalPreferences" AppleKeyboardUIMode -int 2
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/.GlobalPreferences" AppleMiniaturizeOnDoubleClick -bool YES
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/.GlobalPreferences" AppleShowAllExtensions -bool YES
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/.GlobalPreferences" AppleShowScrollBars -string "Always"
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/.GlobalPreferences" NSAutomaticSpellingCorrectionEnabled -bool NO
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/.GlobalPreferences" NSAutomaticWindowAnimationsEnabled -bool NO
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/.GlobalPreferences" NSNavPanelExpandedStateForSaveMode -bool YES
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/.GlobalPreferences" NSQuitAlwaysKeepsWindows -bool NO
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/.GlobalPreferences" PMPrintingExpandedStateForPrint -bool YES
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/.GlobalPreferences" com.apple.swipescrolldirection -bool NO
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/.GlobalPreferences" com.apple.keyboard.fnState -bool YES
       fi
      done
      
      #* Create LOCAL ADMIN ACCOUNT.
      #+ Note : Redirecting home directory to /var so regular end users don't see the local admin home directory at all.
      #+ Note : Consider UniqueID in regard to the Hide500Users value for /Library/Preferences/com.apple.loginwindow
      #+ Note : kcpassword cannot be scripted, you must supply it.
      #+ Note : You may want to consider creating more than one local ADMIN account. For example, one full admin and one with ARD permissions.
      #+ Note : The password is set via plain text, you could supply a pre-made hash file to be more secure. Each user has their own shadow file, with each shadow file stored under a .plist file located in /var/db/dslocal/nodes/Default/users/. The associated hash contains the users GUID which can be found by running dscl localhost -read /Search/Users/ | grep GeneratedUID | cut -c15-
      
      #+ Create the user.
      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 "${UNIQUEID}"
      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}"
      #+ Permissions.
      sudo /usr/sbin/chown -R ${SHORTNAME}:admin "/var/${SHORTNAME}"
      #+ Hide the user from the loginwindow.
      sudo /usr/bin/defaults write "/Library/Preferences/com.apple.loginwindow" HiddenUsersList -array-add ${SHORTNAME}
      
      #* Enable autoLoginUser for this user so "boot" phase is seamless.
      sudo /usr/bin/defaults write "/Library/Preferences/com.apple.loginwindow" autoLoginUser -string "${SHORTNAME}"
      #+ kcpassword payload
      sudo /bin/cp -f "/var/root/kcpassword" "/etc/kcpassword"
      sudo /bin/rm -Rf "/etc/kcpassword.disabled"
      #+ kcpassword special permissions.
      sudo /usr/sbin/chown root:wheel "/etc/kcpassword"
      sudo /bin/chmod 600 "/etc/kcpassword"
      
      #* VNC password
      ENCVNCPASSWD=$(/bin/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 SSH
      sudo /usr/bin/defaults delete "/System/Library/LaunchDaemons/ssh" "Disabled"
      #+ SSH daemon special permissions.
      sudo /usr/sbin/chown root:wheel "/System/Library/LaunchDaemons/ssh.plist"
      sudo /bin/chmod 644 "/System/Library/LaunchDaemons/ssh.plist"
      #+ SSH MOTD banner.
      sudo /bin/echo " " > "/etc/motd"
      sudo /bin/echo "Unauthorized access to these resources is prohibited." >> "/etc/motd"
      sudo /bin/echo " " >> "/etc/motd"
      #+ SSH MOTD special permissions.
      sudo /bin/chmod 755 "/etc/motd"
      sudo /usr/sbin/chown root:wheel "/etc/motd"
      
      #* Enable Apple Remote Desktop
      #+ Note : Check kickstart options, you can make it more secure by using -allowAccessFor -specifiedUsers
      sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -activate -configure -allowAccessFor -allUsers -access -on -privs -all -clientopts -setvnclegacy -vnclegacy yes
      
      #* Disable softwareupdate schedule with a daemon.
      #+ NOTE : softwareupdate plist is machine specific, I do it this way so any future user that logs in has it disabled.
      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"
      #+ softwareupdate Launch Daemon special permissions.
      sudo /usr/sbin/chown root:wheel "/Library/LaunchDaemons/org.softwareupdate.plist"
      sudo /bin/chmod 644 "/Library/LaunchDaemons/org.softwareupdate.plist"
      
      #* Remove dockfixup, most end users don't require any of the iLife apps for work purposes.
      sudo /bin/mv -f /Library/Preferences/com.apple.dockfixup.plist{,.BACKUP}
      
      #* Disable /Library/Printers/PPDs
      #+ NOTE : This is a legacy setting I used to do as Quark populates its print dialog with every PPD. Will go away soon.
      sudo /bin/cp -R /Library/Printers/PPDs/Contents/Resources /Library/PrintersPPDsDisabled
      sudo /bin/rm -R /Library/Printers/PPDs/Contents/Resources/*.*
      
      #* Disable /System/Library/Printers/PPDs
      #+ NOTE : This is a legacy setting I used to do as Quark populates its print dialog with every PPD. Will go away soon.
      sudo /bin/cp -R /System/Library/Printers/PPDs/Contents/Resources /System/Library/PrintersPPDsDisabled
      sudo /bin/rm -R /System/Library/Printers/PPDs/Contents/Resources/*.*
      
      #* Enable Access for Assistive Devices.
      #+ NOTE : Enabling this for applescripts that need to manipulate the GUI.
      sudo touch /private/var/db/.AccessibilityAPIEnabled
      
      #* Link to Directory Utility.
      #+ NOTE : Because its more convenient than 5 clicks!
      sudo /bin/ln -s "/System/Library/CoreServices/Directory Utility.app" "/Applications/Utilities/Directory Utility.app"
      
      #* Turn down default volume
      #+ NOTE : So the "boot" phase doesn't surprise anyone :)
      sudo /usr/bin/osascript -e "set Volume 2"
      
      #* Disable QuickLook Daemon
      #+ Rather than constantly clearing /Users/USER/Library/Caches/com.apple.QuickLookDaemon
      /usr/bin/defaults write "/System/Library/LaunchAgents/com.apple.quicklook" Disabled -bool true
      
      #* Remove Alex and save 450mb, smaller DMG size.
      sudo /bin/rm -Rf "/System/Library/Speech/Voices/Alex.SpeechVoice"
      
      #* Remove any sleepimage, smaller DMG size.
      #+ NOTE : Only do this if you understand what its doing. Google it.
      sudo /bin/rm -Rf "/private/var/vm/sleepimage"
      
      #* Remove any swapfile, smaller DMG size.
      sudo /bin/rm -Rf "/private/var/vm/swapfile0"
      
      #* Remove caches just-in-case there is anything machine specific.
      sudo /bin/rm -Rf ~/Library/Caches/*
      sudo /bin/rm -Rf /Library/Caches/*
      sudo /bin/rm -Rf /System/Library/Caches/*
      
      #* Remove preferences just-in-case there is anything machine specific.
      sudo /bin/rm -Rf /Library/Preferences/SystemConfiguration/CaptiveNetworkSupport/Settings.plist
      sudo /bin/rm -Rf /Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist
      sudo /bin/rm -Rf /Library/Preferences/SystemConfiguration/com.apple.Boot.plist
      sudo /bin/rm -Rf /Library/Preferences/SystemConfiguration/com.apple.network.identification.plist
      sudo /bin/rm -Rf /Library/Preferences/SystemConfiguration/com.apple.PowerManagement.plist
      sudo /bin/rm -Rf /Library/Preferences/SystemConfiguration/NetworkInterfaces.plist
      sudo /bin/rm -Rf /Library/Preferences/SystemConfiguration/preferences.plist
      
      #* Set "boot" phase LoginHook.
      #+ Use to run scripts that cannot be added to the "build" phase.
      sudo /usr/bin/defaults write "/var/root/Library/Preferences/com.apple.loginwindow" LoginHook -string "/var/root/boot.sh"
      
      
    • boot.sh
      #* boot.sh
      #+ Phase 2 of 3
      #+ This script runs as a LoginHook to prep a Mac OS X 10.7.3 prior to the localise phase.
      
      #* PLIST BUDDY
      PB="/usr/libexec/PlistBuddy"
      
      #* 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)
      
      #* Model.
      MODEL=$(sudo /usr/sbin/ioreg -rd1 -c IOPlatformExpertDevice | /usr/bin/grep -E model | /usr/bin/awk '{print $3}' | /usr/bin/sed 's/\<\"//' | sed 's/\"\>//')
      
      #* Set Computer name,Local Host Name, Hostname, Netbios name.
      #+ NOTE : I do this so the machine is easily identifiable during first boot via Apple Remote Desktop Administrator client. I support sites remotely.
      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}"
      
      #* Set info2 field in ARD.
      #+ NOTE : I do this simply so I can quickly see machine models via ARD (so I know which macs can/can't be upgraded to the latest OS. I don't buy upgrades, I simply create images for the OS that the mac ships with.
      sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -computerinfo -set2 -2 "${MODEL}"
      
      #* Set Computer sleep idle time, Display sleep idle time, Disable hard disk sleep.
      #+ NOTE : So the hard disk doesn't go to sleep on me while supporting remotely.
      sudo /usr/sbin/systemsetup -setcomputersleep "60"
      sudo /usr/sbin/systemsetup -setdisplaysleep "15"
      sudo /usr/sbin/systemsetup -setharddisksleep off
      
      #* Disable ipv6.
      #+ NOTE : Issues have been reported regarding Binding to AD if IPv6 is enabled so I turn it off. (don't use IPv6 yet anyway)
      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 Services.
      #+ NOTE : Issues have been reported with certain VPN profile setups if services don't have priority. Won't explain here, too detailed. Email me if you want details.
      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"
      
      #* Disable Un-necessary network services.
      sudo sudo /usr/sbin/networksetup -setnetworkserviceenabled "Bluetooth DUN" "off"
      sudo sudo /usr/sbin/networksetup -setnetworkserviceenabled "Bluetooth PAN" "off"
      sudo /usr/sbin/networksetup -setnetworkserviceenabled "FireWire" "off"
      
      #* Disable Airport Power
      #+ NOTE : Mainly to reduce LAN noise. You could limit this to non-laptops.
      sudo /usr/sbin/networksetup -setairportpower "en1" "off"
      
      #* Default preferences.
      #+ Modifies /System/Library/User Template
      #+ Note : Must do during first boot as plist files contain UUID or MACADDRESS
      #+ Note : At some point Apple changed certain modesl from using MACADDRESS and instead now use UUID. I can't be bothered figuring it out so just writing one of each.
      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"
        # Ensure ByHost is there
        sudo /bin/mkdir -p "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost"
        # 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 $PB -c 'Add :CleanExit string YES' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${UUID}.plist"
        sudo $PB -c 'Add :idleTime integer 900' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${UUID}.plist"
        sudo $PB -c 'Add :moduleDict dict' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${UUID}.plist"
        sudo $PB -c 'Add :moduleDict:iLifeMediaGroupType integer 0' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${UUID}.plist"
        sudo $PB -c 'Add :moduleDict:moduleName string ${YOURSCREENSAVER}' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${UUID}.plist"
        sudo $PB -c 'Add :moduleDict:path string /Library/Screen\ Savers/${YOURSCREENSAVER}.slideSaver' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${UUID}.plist"
        sudo $PB -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 $PB -c 'Add :CleanExit string YES' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${MACADDRESS}.plist"
        sudo $PB -c 'Add :idleTime integer 900' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${MACADDRESS}.plist"
        sudo $PB -c 'Add :moduleDict dict' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${MACADDRESS}.plist"
        sudo $PB -c 'Add :moduleDict:iLifeMediaGroupType integer 0' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${MACADDRESS}.plist"
        sudo $PB -c 'Add :moduleDict:moduleName string ${YOURSCREENSAVER}' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${MACADDRESS}.plist"
        sudo $PB -c 'Add :moduleDict:path string /Library/Screen\ Savers/${YOURSCREENSAVER}.slideSaver' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${MACADDRESS}.plist"
        sudo $PB -c 'Add :moduleDict:type integer 4' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.screensaver.${MACADDRESS}.plist"
        # Laptop?
        ioreg -rd1 -c IOPlatformExpertDevice | grep -E model | awk '{print $3}' | sed s/\<\"// | sed s/\"\>// | grep iMac
        if [ "$?" == "1" ]; then
         # com.apple.systemuiserver.plist for laptop
         sudo $PB -c 'Delete menuExtras' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systemuiserver.plist" 
         sudo $PB -c 'Add menuExtras array' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systemuiserver.plist" 
         sudo $PB -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 $PB -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 $PB -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 $PB -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 $PB -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 $PB -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 $PB -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 $PB -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 $PB -c 'Add menuExtras:8 string /System/Library/CoreServices/Menu\ Extras/Battery.menu' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systemuiserver.plist"
         # com.apple.systemuiserver.${UUID}.plist (do not load) for laptop
         sudo $PB -c 'Delete dontAutoLoad' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${UUID}.plist" 
         sudo $PB -c 'Add dontAutoLoad array' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${UUID}.plist" 
         sudo $PB -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) for laptop
         sudo $PB -c 'Delete dontAutoLoad' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${MACADDRESS}.plist" 
         sudo $PB -c 'Add dontAutoLoad array' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${MACADDRESS}.plist" 
         sudo $PB -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"
        else
         # com.apple.systemuiserver.plist for non-laptop
         sudo $PB -c 'Add menuExtras array' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.systemuiserver.plist" 
         sudo $PB -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 $PB -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 $PB -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 $PB -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 $PB -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 $PB -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) for non-laptop
         sudo $PB -c 'Add dontAutoLoad array' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${UUID}.plist" 
         sudo $PB -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 $PB -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 $PB -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 $PB -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) for non-laptop
         sudo $PB -c 'Add dontAutoLoad array' "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/ByHost/com.apple.systemuiserver.${MACADDRESS}.plist" 
         sudo $PB -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 $PB -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 $PB -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 $PB -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
       fi
      done
      
      #* Disable "boot" phase LoginHook
      sudo /usr/bin/defaults delete "/var/root/Library/Preferences/com.apple.loginwindow" LoginHook
      
      #* Installing Updates
      #+ NOTE : This is for pkgs that require boot volume
      #+ NOTE : You need to add relevant .pkgs to /var/root/Updates
      find /var/root/Updates -name .DS_Store -exec rm {} \;
      for i in `ls /var/root/Updates`
      do
       /bin/echo "Installing $i"
       sudo installer -pkg /var/root/$i -target /
      done
      
      
    • localise.sh
      #* localise.sh
      #+ Phase 3 of 3
      #+ This script is run manually (I do it with an Applescript GUI wrapper). To be used for localisation as I support multiple sites (languages, locales, timezones etc etc)
      
      #* PLIST BUDDY
      PB="/usr/libexec/PlistBuddy"
      
      #* Apple unique workstation UUID.
      UUID=$(/usr/sbin/ioreg -rd1 -c IOPlatformExpertDevice | /usr/bin/perl -ne 'if (m/^.*\"IOPlatformUUID\" = \"(.*).*\"$/im) {print $1}')
      
      #* 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)
      
      # Model.
      MODEL=$(sudo /usr/sbin/ioreg -rd1 -c IOPlatformExpertDevice | /usr/bin/grep -E model | /usr/bin/awk '{print $3}' | /usr/bin/sed 's/\<\"//' | sed 's/\"\>//')
      
      #* OS
      OS=`/usr/bin/sw_vers | grep ProductVersion | awk '{print $2}'`
      
      #* RAM
      RAM=`/usr/sbin/system_profiler SPHardwareDataType | grep "Memory" | awk '{print $2$3}'`
      
      #* CPU
      CPU=`/usr/sbin/system_profiler SPHardwareDataType | grep "Processor Name" | awk '{print $3$4$5$6$7$8$9}'`
      
      #* Set the workstation ComputerName, LocalHostName,hostname and NetBIOSName
      logger "POSTBUILD PHASE : ComputerName ${ComputerName}"
      sudo /usr/sbin/scutil --set ComputerName "${ComputerName}"
      logger "POSTBUILD PHASE : LocalHostName ${LocalHostName}"
      sudo /usr/sbin/scutil --set LocalHostName "${LocalHostName}"
      logger "POSTBUILD PHASE : hostname ${hostname}"
      sudo /bin/hostname "${hostname}"
      logger "POSTBUILD PHASE : HostName ${HostName}"
      sudo /usr/sbin/scutil --set HostName "${HostName}"
      logger "POSTBUILD PHASE : NetBIOSName ${NetBIOSName}"
      sudo /usr/bin/defaults write /Library/Preferences/SystemConfiguration/com.apple.smb.server NetBIOSName "${NetBIOSName}"
      
      #* Set the default workstation language
      #+ NOTE : Refer to the xxx.lproj User Template folders as a quick guide (where xxx is the ${language} string). So for english it would be languagesetup -langspec "English" but for Portuguese it would be languagesetup -langspec "pt"
      #+ NOTE : languagesetup zaps /Library/Preferences/.GlobalPreferences so make sure you set the language early ;)
      logger "POSTBUILD PHASE : Language ${language}"
      sudo /usr/sbin/languagesetup -langspec "${language}"
      
      #* Set the default workstation locale
      #+ NOTE : Values consist of Language and Country in the format xx_xx, refer to /usr/share/locale for acceptable values.
      logger "POSTBUILD PHASE : AppleLocale ${locale}"
      sudo /usr/bin/defaults write /Library/Preferences/.GlobalPreferences AppleLocale -string "${locale}"
      
      #* Set the default workstation country
      #+ NOTE : Refer to /usr/share/locale for acceptable values.
      logger "POSTBUILD PHASE : Country ${country}"
      sudo /usr/bin/defaults write /Library/Preferences/.GlobalPreferences Country -string "${country}"
      
      #* Set the default workstation measurement units
      #+ NOTE : Metric is either TRUE or FALSE and Measurement Units is either Inches or Centimeters.
      logger "POSTBUILD PHASE : AppleMeasurementUnits ${applemeasurementunits}"
      sudo /usr/bin/defaults write /Library/Preferences/.GlobalPreferences AppleMeasurementUnits -string "${applemeasurementunits}"
      logger "POSTBUILD PHASE : AppleMetricUnits ${applemetricunits}"
      sudo /usr/bin/defaults write /Library/Preferences/.GlobalPreferences AppleMetricUnits -string "${applemetricunits}"
      
      #* Set default workstation "System" Input Keyboard Layout
      #+ NOTE : The permissions are important otherwise it won't work. I haven't found a reliable source of values anywhere, had to do this manually for each location to capture the values the first time.
      logger "POSTBUILD PHASE - Input Keyboard Layout id : ${keyboardlayoutid}"
      logger "POSTBUILD PHASE - Input Keyboard Layout name : ${keyboardlayoutname}"
      sudo $PB -c "Add :AppleCurrentKeyboardLayoutInputSourceID string com.apple.keylayout.${keyboardlayoutname}" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Set :AppleCurrentKeyboardLayoutInputSourceID com.apple.keylayout.${keyboardlayoutname}" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Delete :AppleDefaultAsciiInputSource" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Add :AppleDefaultAsciiInputSource:InputSourceKind string Keyboard\ Layout" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Set :AppleDefaultAsciiInputSource:InputSourceKind Keyboard\ Layout" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Add :AppleDefaultAsciiInputSource:KeyboardLayout\ ID integer ${keyboardlayoutid}" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Set :AppleDefaultAsciiInputSource:KeyboardLayout\ ID ${keyboardlayoutid}" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Add :AppleDefaultAsciiInputSource:KeyboardLayout\ Name string ${keyboardlayoutname}" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Set :AppleDefaultAsciiInputSource:KeyboardLayout\ Name ${keyboardlayoutname}" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Delete :AppleEnabledInputSources" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Add :AppleEnabledInputSources:0 dict" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Add :AppleEnabledInputSources:0:InputSourceKind string Keyboard\ Layout" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Set :AppleEnabledInputSources:0:InputSourceKind Keyboard\ Layout" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Add :AppleEnabledInputSources:0:KeyboardLayout\ ID integer ${keyboardlayoutid}" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Set :AppleEnabledInputSources:0:KeyboardLayout\ ID ${keyboardlayoutid}" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Add :AppleEnabledInputSources:0:KeyboardLayout\ Name string ${keyboardlayoutname}" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Set :AppleEnabledInputSources:0:KeyboardLayout\ Name ${keyboardlayoutname}" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Delete :AppleSelectedInputSources" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Add :AppleSelectedInputSources:0 dict" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Add :AppleSelectedInputSources:0:InputSourceKind string Keyboard\ Layout" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Set :AppleSelectedInputSources:0:InputSourceKind Keyboard\ Layout" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Add :AppleSelectedInputSources:0:KeyboardLayout\ ID integer ${keyboardlayoutid}" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Set :AppleSelectedInputSources:0:KeyboardLayout\ ID ${keyboardlayoutid}" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Add :AppleSelectedInputSources:0:KeyboardLayout\ Name string ${keyboardlayoutname}" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo $PB -c "Set :AppleSelectedInputSources:0:KeyboardLayout\ Name ${keyboardlayoutname}" "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo chown root:admin "/Library/Preferences/com.apple.HIToolbox.plist"
      sudo chmod 644 "/Library/Preferences/com.apple.HIToolbox.plist"
      
      #* Set default workstation "LoginWindow" Input Keyboard Layout
      #+ NOTE : The permissions are important otherwise it won't work. 
      logger "POSTBUILD PHASE - Loginwindow Keyboard Layout id : ${keyboardlayoutid}"
      logger "POSTBUILD PHASE - Loginwindow Keyboard Layout name : ${keyboardlayoutname}"
      sudo $PB -c "Add :AppleCurrentKeyboardLayoutInputSourceID string com.apple.keylayout.${keyboardlayoutname}" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Set :AppleCurrentKeyboardLayoutInputSourceID com.apple.keylayout.${keyboardlayoutname}" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Add :com.apple.HIToolbox dict" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Delete :com.apple.HIToolbox:AppleDefaultAsciiInputSource" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Add :com.apple.HIToolbox:AppleDefaultAsciiInputSource array" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Add :com.apple.HIToolbox:AppleDefaultAsciiInputSource:InputSourceKind string Keyboard\ Layout" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Set :com.apple.HIToolbox:AppleDefaultAsciiInputSource:InputSourceKind Keyboard\ Layout" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Add :com.apple.HIToolbox:AppleDefaultAsciiInputSource:KeyboardLayout\ ID integer ${keyboardlayoutid}" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Set :com.apple.HIToolbox:AppleDefaultAsciiInputSource:KeyboardLayout\ ID ${keyboardlayoutid}" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Add :com.apple.HIToolbox:AppleDefaultAsciiInputSource:KeyboardLayout\ Name string ${keyboardlayoutname}" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Set :com.apple.HIToolbox:AppleDefaultAsciiInputSource:KeyboardLayout\ Name ${keyboardlayoutname}" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Delete :com.apple.HIToolbox:AppleEnabledInputSources" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Add :com.apple.HIToolbox:AppleEnabledInputSources array" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Add :com.apple.HIToolbox:AppleEnabledInputSources:0 dict" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Add :com.apple.HIToolbox:AppleEnabledInputSources:0:InputSourceKind string Keyboard\ Layout" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Set :com.apple.HIToolbox:AppleEnabledInputSources:0:InputSourceKind Keyboard\ Layout" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Add :com.apple.HIToolbox:AppleEnabledInputSources:0:KeyboardLayout\ ID integer ${keyboardlayoutid}" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Set :com.apple.HIToolbox:AppleEnabledInputSources:0:KeyboardLayout\ ID ${keyboardlayoutid}" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Add :com.apple.HIToolbox:AppleEnabledInputSources:0:KeyboardLayout\ Name string ${keyboardlayoutname}" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Set :com.apple.HIToolbox:AppleEnabledInputSources:0:KeyboardLayout\ Name ${keyboardlayoutname}" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Delete :com.apple.HIToolbox:AppleSelectedInputSources" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Add :com.apple.HIToolbox:AppleSelectedInputSources array" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Add :com.apple.HIToolbox:AppleSelectedInputSources:0 dict" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Add :com.apple.HIToolbox:AppleSelectedInputSources:0:InputSourceKind string Keyboard\ Layout" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Set :com.apple.HIToolbox:AppleSelectedInputSources:0:InputSourceKind Keyboard\ Layout" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Add :com.apple.HIToolbox:AppleSelectedInputSources:0:KeyboardLayout\ ID integer ${keyboardlayoutid}" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Set :com.apple.HIToolbox:AppleSelectedInputSources:0:KeyboardLayout\ ID ${keyboardlayoutid}" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Add :com.apple.HIToolbox:AppleSelectedInputSources:0:KeyboardLayout\ Name string ${keyboardlayoutname}" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo $PB -c "Set :com.apple.HIToolbox:AppleSelectedInputSources:0:KeyboardLayout\ Name ${keyboardlayoutname}" "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      # Special Explicit Permissions!!!
      sudo chown securityagent:wheel "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      sudo chmod 644 "/var/tmp/com.apple.HIToolbox.loginwindow.plist"
      
      #* Set Visibility Input Keyboard Layout Menu in Loginwindow
      logger "POSTBUILD PHASE - Loginwindow : showInputMenu"
      sudo defaults write /Library/Preferences/com.apple.loginwindow showInputMenu -bool "TRUE"
      logger "POSTBUILD PHASE - Loginwindow : ModeNameVisible"
      sudo defaults write /var/ard/Library/Preferences/com.apple.menuextra.textinput ModeNameVisible -bool "TRUE"
      sudo chmod 777 /Library/Preferences/com.apple.loginwindow.plist
      
      #* Set default workstation network time server
      logger "POSTBUILD PHASE : setnetworktimeserver ${timeserver}"
      sudo /usr/sbin/systemsetup -setusingnetworktime "on"
      sudo /usr/sbin/systemsetup -setnetworktimeserver "${networktimeserver}"
      
      #* Set default workstation timezone
      #+ NOTE : Refer to /usr/sbin/systemsetup -listtimezones for acceptable values.
      logger "POSTBUILD PHASE : settimezone ${timezone}"
      sudo /usr/sbin/systemsetup -settimezone "${timezone}"
      
      #* Energy Saver Defaults
      logger "POSTBUILD PHASE : /Library/Preferences/com.apple.PowerManagement"
      sudo /usr/sbin/systemsetup -setallowpowerbuttontosleepcomputer "off"
      sudo /usr/sbin/systemsetup -setcomputersleep "60"
      sudo /usr/sbin/systemsetup -setdisplaysleep "45"
      sudo /usr/sbin/systemsetup -setharddisksleep "off"
      sudo /usr/sbin/systemsetup -setrestartpowerfailure "off"
      sudo /usr/sbin/systemsetup -setwakeonnetworkaccess "on"
      
      #* Modify authorizations
      #+ NOTE : if you don't know what this is you probably shouldn't mess with it ;) email me and I'll explain chris.gerke@gmail.com
      
      #+ Backup Original
      logger "POSTBUILD PHASE : /etc/authorization"
      sudo /bin/cp -f /etc/authorization{,.original}
      #+ Allow date & time preference pane access.
      sudo $PB -c "set rights:system.preferences.datetime:class allow" "/etc/authorization"
      sudo $PB -c "delete rights:system.preferences.datetime:shared" "/etc/authorization"
      sudo $PB -c "delete rights:system.preferences.datetime:group" "/etc/authorization"
      #+ Allow DVD region setting rights
      sudo $PB -c "add rights:system.device.dvd.setregion.change dict" "/etc/authorization"
      sudo $PB -c "add rights:system.device.dvd.setregion.change:class string" "/etc/authorization"
      sudo $PB -c "set rights:system.device.dvd.setregion.change:class allow" "/etc/authorization"
      sudo $PB -c "delete rights:system.device.dvd.setregion.change:shared" "/etc/authorization"
      sudo $PB -c "delete rights:system.device.dvd.setregion.change:group" "/etc/authorization"
      #+ Allow DVD region initial setting rights
      sudo $PB -c "set rights:system.device.dvd.setregion.initial:class allow" "/etc/authorization"
      sudo $PB -c "delete rights:system.device.dvd.setregion.initial:shared" "/etc/authorization"
      sudo $PB -c "delete rights:system.device.dvd.setregion.initial:group" "/etc/authorization"
      #+ Allow network preference pane access
      sudo $PB -c "set rights:system.preferences.network:class allow" "/etc/authorization"
      sudo $PB -c "delete rights:system.preferences.network:shared" "/etc/authorization"
      sudo $PB -c "delete rights:system.preferences.network:group" "/etc/authorization"
      #+ Change /etc/authorization to allow all users to open preference panes
      sudo $PB -c "set rights:system.preferences.printing:class allow" "/etc/authorization"
      sudo $PB -c "delete rights:system.preferences.printing:shared" "/etc/authorization"
      sudo $PB -c "delete rights:system.preferences.printing:group" "/etc/authorization"
      #+ Allow preference panes
      sudo $PB -c "set rights:system.preferences:class allow" "/etc/authorization"
      sudo $PB -c "delete rights:system.preferences:shared" "/etc/authorization"
      sudo $PB -c "delete rights:system.preferences:group" "/etc/authorization"
      #+ Allow print admin rights
      sudo $PB -c "set rights:system.print.admin:class allow" "/etc/authorization"
      sudo $PB -c "delete rights:system.print.admin:group" "/etc/authorization"
      sudo $PB -c "delete rights:system.print.admin:shared" "/etc/authorization"
      #+ Allow printing manager rights
      sudo $PB -c "set rights:system.printingmanager:class allow" "/etc/authorization"
      sudo $PB -c "delete rights:system.printingmanager:rule" "/etc/authorization"
      #+ Permissions
      sudo chown root:wheel "/etc/authorization"
      sudo chmod 644 "/etc/authorization"
      
      #* Require admin password for comp-to-comp wifi
      logger "POSTBUILD PHASE : RequireAdminIBSS"
      sudo /usr/libexec/airportd en1 prefs RequireAdminIBSS=YES
      
      #* Disable font protection because designers persist in using PS versions of system dfonts so we have to cusotmise it later!! arrgghhhh
      logger "POSTBUILD PHASE : fontprotection -off"
      sudo /usr/bin/atsutil fontprotection -off
      
      #* Set default font server
      logger "POSTBUILD PHASE : Setting ${fontserver}"
      sudo echo "server.address=${fontserver}" > "/Library/Preferences/com.extensis.UniversalTypeClient.conf"
      sudo echo "server.port=${fontport}" >> "/Library/Preferences/com.extensis.UniversalTypeClient.conf"
      
      #* Default preferences.
      #+ Modifies /System/Library/User Template
      #+ I do it here because each site has a custom intranet page, for security reasons not adding the extra bits that set DNS but you get the idea....
      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"
        # Safari
        logger "POSTBUILD PHASE : Homepage $url"
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.internetconfigpriv" WWWHomePage $url
        sudo /usr/bin/defaults write "/System/Library/User Template/${USER_TEMPLATE}/Library/Preferences/com.apple.Safari" HomePage $url
       fi  
      done
      
      #* Setup the Login Window, add a banner.
      logger "POSTBUILD PHASE : Loginwindow"
      sudo /usr/bin/defaults write /Library/Preferences/com.apple.loginwindow LoginwindowText -string "$LoginWindowText"
      #+ Username and Password fields instead of user badges
      sudo /usr/bin/defaults write /Library/Preferences/com.apple.loginwindow SHOWFULLNAME -bool "TRUE"
      #+ Show host info
      sudo /usr/bin/defaults write /Library/Preferences/com.apple.loginwindow AdminHostInfo "DSStatus"
      #+ 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
      #+ Add a delay to avoid authentication issues on machines with slow DCHP leases
      sudo /usr/bin/defaults write /Library/Preferences/com.apple.loginwindow StartupDelay -int 13
      
      #* Bind to AD.
      #+ NOTE : This is done with ADMItMac, will be testing feasability of using built-in AD in the coming days, will post and update.
      logger "POSTBUILD PHASE : ADMitMac Attempting bind to ${OU}"
      sudo /sbin/amconfig -A -F -c ${hostname}
      logger "POSTBUILD PHASE : ADMitMac Changing User Attribute RecordName to sAMAccountName (shortname for user directory)"
      sudo $PB -c "Set :Record\ Type\ Map:dsRecTypeStandard\:Users:Attribute\ Type\ Map:dsAttrTypeStandard\:RecordName:AD\ Attributes:0 sAMAccountName" /Library/DirectoryServices/Plugins/CIFSPlugin.dsplug/Contents/Resources/LDAPConfig.plist
      sudo $PB -c "Set :Record\ Type\ Map:dsRecTypeStandard\:Users:Attribute\ Type\ Map:dsAttrTypeStandard\:RecordName:AD\ Attributes:2 userPrincipalName" /Library/DirectoryServices/Plugins/CIFSPlugin.dsplug/Contents/Resources/LDAPConfig.plist
      logger "POSTBUILD PHASE : ADMitMac Display Cached Creds Dialog false"
      sudo /usr/bin/defaults write /Library/Preferences/com.thursby.tss_check_cifs "Display Cached Creds Dialog" "false"
      sudo /usr/bin/defaults write /Library/Preferences/com.thursby.CIFSPlugin "LDAP Connect Timeout" 30
      
      #* Set NIC speed for regions that may want hard setting
      logger "POSTBUILD PHASE : NIC Speed"
      sudo /usr/sbin/networksetup -setMedia en0 ${networkspeed} ${networkduplex}
      
      #* Set LoginHook
      logger "POSTBUILD PHASE : LoginHook"
      sudo /usr/bin/defaults write "/var/root/Library/Preferences/com.apple.loginwindow" LoginHook -string "${GlobalLoginHook}"
      
      #* Disable autologin
      sudo /bin/rm -f /var/ard/Library/Keychains/login.keychain
      sudo /usr/bin/defaults write /Library/Preferences/com.apple.loginwindow autoLoginUser ""
      
      #* Repair Permissions (can't run in single user mode)
      sudo /usr/sbin/diskutil repairPermissions /
      
      #* Email workstation details to me, this is a perl script using smtp. Will add a copy in another post.
      sudo /var/root/email.sh
      


That’s all folks.

Probably not…. anyone that makes SOEs knows it never ever ends ;)

Will post any additions I make, the most important part now is test test test.

Filter OSX netboot images by Mac model

Posted 2012/08/14 By mikep345678

From a post on DeployStudio’s forum. It’s not currently live so this is from Google’s cache…

Model Property filtering..How to set in runtime.nbi for multiple macs?

I was able to use System Imaging Utility to create a NBI that had the plist with the Model Property Filtering in it. I then copied the Model Property Filtering plist information into the NBImageInfo.plist in the NBI and the options became available in Server Admin.

I set my 10.5 PPC NBI to not allow G3’s in Server Admin and from what I can tell imaging three G3 machines so far it appears to have worked to keep them from that PPC NBI and let the NBI I made for my G3’s which points to my server hosting DS rc120 pick things up.

Here’s a copy of the text from the NBImageInfo.plist made from System Image Utility:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Architectures</key>
<array>
<string>i386</string>
</array>
<key>BackwardCompatible</key>
<false/>
<key>BootFile</key>
<string>booter</string>
<key>Description</key>
<string>NetBoot of Mac OS X Server 10.6 (10A433) Install.</string>
<key>DisabledSystemIdentifiers</key>
<array>
<string>MacBookPro5,2</string>
<string>MacBookPro5,1</string>
<string>MacBookPro5,5</string>
<string>MacBookPro5,4</string>
<string>MacBookPro5,3</string>
<string>PowerBook5,9</string>
<string>PowerBook3,4</string>
<string>PowerBook6,4</string>
<string>PowerBook5,7</string>
<string>PowerBook3,2</string>
<string>PowerBook6,2</string>
<string>PowerBook5,5</string>
<string>PowerBook5,3</string>
<string>PowerBook5,1</string>
<string>PowerBook3,5</string>
<string>PowerBook5,8</string>
<string>PowerBook3,3</string>
<string>PowerBook5,6</string>
<string>PowerBook3,1</string>
<string>PowerBook6,1</string>
<string>PowerBook5,4</string>
<string>PowerBook5,2</string>
<string>PowerBook6,8</string>
<string>MacBook5,2</string>
<string>MacBook6,1</string>
<string>PowerMac3,3</string>
<string>PowerMac3,6</string>
<string>PowerMac3,2</string>
<string>PowerMac3,5</string>
<string>PowerMac3,1</string>
<string>PowerMac3,4</string>
<string>MacBookPro6,1</string>
<string>MacBookPro6,2</string>
<string>PowerMac12,1</string>
<string>PowerMac8,2</string>
<string>PowerMac8,1</string>
<string>MacBookAir2,1</string>
<string>MacBookAir1,1</string>
<string>PowerBook4,1</string>
<string>PowerBook2,3</string>
<string>PowerBook2,1</string>
<string>PowerBook4,4</string>
<string>PowerBook4,2</string>
<string>PowerBook2,2</string>
<string>PowerBook4,3</string>
<string>MacBookPro1,2</string>
<string>MacBookPro1,1</string>
<string>MacBookPro4,1</string>
<string>MacBookPro3,1</string>
<string>MacBookPro2,2</string>
<string>MacBookPro2,1</string>
<string>iMac10,1</string>
<string>MacPro1,1</string>
<string>MacPro3,1</string>
<string>MacPro1,1,Quad</string>
<string>MacPro2,1</string>
<string>PowerMac6,3</string>
<string>PowerMac4,2</string>
<string>PowerMac4,5</string>
<string>PowerMac6,1</string>
<string>MacBook1,1</string>
<string>iMac7,1</string>
<string>iMac8,1</string>
<string>iMac9,1</string>
<string>Xserve2,1</string>
<string>PowerBook1,1</string>
<string>MacBookPro7,1</string>
<string>MacBook5,1</string>
<string>PowerMac2,2</string>
<string>PowerMac2,1</string>
<string>PowerMac4,1</string>
<string>RackMac1,1</string>
<string>RackMac1,2</string>
<string>MacBook7,1</string>
<string>PowerMac10,2</string>
<string>PowerMac10,1</string>
<string>MacBook3,1</string>
<string>MacBook4,1</string>
<string>MacBook2,1</string>
<string>PowerMac5,2</string>
<string>PowerMac5,1</string>
<string>Macmini2,1</string>
<string>Macmini3,1</string>
<string>Macmini1,1</string>
<string>iMac4,2</string>
<string>iMac4,1</string>
<string>Xserve1,1</string>
<string>RackMac3,1</string>
<string>iMac11,1</string>
<string>PowerMac9,1</string>
<string>PowerMac11,2,Quad</string>
<string>PowerMac7,3</string>
<string>PowerMac11,2</string>
<string>PowerMac7,2</string>
<string>PowerMac6,4</string>
<string>PowerMac4,4</string>
<string>iMac5,2</string>
<string>iMac5,1</string>
<string>iMac6,1</string>
<string>PowerBook6,7</string>
<string>PowerBook6,5</string>
<string>PowerBook6,3</string>
<string>Xserve3,1</string>
<string>PowerMac1,2</string>
<string>PowerMac1,1</string>
<string>MacPro4,1</string>
</array>
<key>EnabledSystemIdentifiers</key>
<array/>
<key>Index</key>
<integer>1632</integer>
<key>IsDefault</key>
<false/>
<key>IsEnabled</key>
<false/>
<key>IsInstall</key>
<false/>
<key>Kind</key>
<integer>2</integer>
<key>Language</key>
<string>Default</string>
<key>Name</key>
<string>NetBoot of Mac OS 10.6 Server Install Disc</string>
<key>RootPath</key>
<string>NetBoot.dmg</string>
<key>SupportsDiskless</key>
<false/>
<key>Type</key>
<string>NFS</string>
<key>osVersion</key>
<string>10.6</string>
</dict>
</plist>

Remove iWork ’09 via script

Posted 2012/08/13 By mikep345678

Found an applescript written by Yvan KOENIG to remove iWork ’09 from a machine. Have converted it to bash so it can more easily be deployed via ARD and as a pre-flight to the installation package in munki.

#!/bin/sh

rm -rf "/Library/com.apple.iWork09.Installer.plist"
rm -rf "/Library/com.apple.iWork09.plist"
rm -rf "/Library/Application Support/iWork '09/"
rm -rf "/Library/Receipts/iWork09Trial.pkg"
rm -rf "/Library/Documentation/Help/iWorkFunctionsHelp.help"
rm -rf "/Applications/iWork '09/"
rm -rf "/Applications/Keynote.app "
rm -rf "/Applications/Numbers.app "
rm -rf "/Applications/Pages.app "

defaultprofile="/System/Library/User Template/English.lproj"

rm -rf "$defaultprofile""/Library/Caches/com.apple.iWork.Fonts"
rm -rf "$defaultprofile""/Library/Caches/com.apple.iWork.Keynote"
rm -rf "$defaultprofile""/Library/Caches/com.apple.iWork.Numbers"
rm -rf "$defaultprofile""/Library/Caches/com.apple.iWork.Pages"
rm -rf "$defaultprofile""/Library/Preferences/com.apple.iWork.Keynote.plist"
rm -rf "$defaultprofile""/Library/Preferences/com.apple.iWork.Numbers.plist"
rm -rf "$defaultprofile""/Library/Preferences/com.apple.iWork.Pages.plist"
rm -rf "$defaultprofile""/Library/Preferences/com.apple.iWork.Keynote.LSSharedFileList.plist"
rm -rf "$defaultprofile""/Library/Preferences/com.apple.iWork.Numbers.LSSharedFileList.plist"
rm -rf "$defaultprofile""/Library/Preferences/com.apple.iWork.Pages.LSSharedFileList.plist"
rm -rf "$defaultprofile""/Applications/iWork '09/"
rm -rf "$defaultprofile""/Applications/Keynote.app"
rm -rf "$defaultprofile""/Applications/Numbers.app"
rm -rf "$defaultprofile""/Applications/Pages.app"

for userNames in /Users/*
do
rm -rf "/Users/$userNames/Library/Caches/com.apple.iWork.Fonts"
rm -rf "/Users/$userNames/Library/Caches/com.apple.iWork.Keynote"
rm -rf "/Users/$userNames/Library/Caches/com.apple.iWork.Numbers"
rm -rf "/Users/$userNames/Library/Caches/com.apple.iWork.Pages"
rm -rf "/Users/$userNames/Library/Preferences/com.apple.iWork.Keynote.plist"
rm -rf "/Users/$userNames/Library/Preferences/com.apple.iWork.Numbers.plist"
rm -rf "/Users/$userNames/Library/Preferences/com.apple.iWork.Pages.plist"
rm -rf "/Users/$userNames/Library/Preferences/com.apple.iWork.Keynote.LSSharedFileList.plist"
rm -rf "/Users/$userNames/Library/Preferences/com.apple.iWork.Numbers.LSSharedFileList.plist"
rm -rf "/Users/$userNames/Library/Preferences/com.apple.iWork.Pages.LSSharedFileList.plist"
rm -rf "/Users/$userNames/Applications/iWork '09/"
rm -rf "/Users/$userNames/Applications/Keynote.app"
rm -rf "/Users/$userNames/Applications/Numbers.app"
rm -rf "/Users/$userNames/Applications/Pages.app"
done

exit 0

determine Linux directory sizes

Posted 2012/07/01 By mikep345678

Summarizes size of home folder excluding Dropbox, Downloads, Videos, Trash:
du -sh --exclude "Dropbox" --exclude "Downloads" --exclude "Videos" --exclude "Trash" ~/
 

Shows size of subfolders (1 deep) with same excludes:
du -h -d 1 --exclude "Dropbox" --exclude "Downloads" --exclude "Videos" --exclude "Trash" ~/
 

Using DeployStudio in a Dual Platform Environment

Posted 2012/05/24 By mikep345678

(Another post copied from someone else [wiki.sdsm.k12.wi.us/users/tmetallo/weblog/49560/Using_DeployStudio_in_a_Dual_Platform_Environment.html  perhaps?]– but the original doesn’t seem to be around any more, so this is from Google’s cache…)

Using DeployStudio in a Dual Platform Environment

Summary of our Environment

  • We are running a single, Dual quad core 2.8 GHz, XServer with OS 10.6.6 and 8 GB RAM.
  • We are running the standard NetBoot service on our Mac server.
  • We are running DeployStudio 1.0rc125 (100127).
  • We have roughly 240 OS 10.6.4 Macs (approx. 100 dual boot) and 900 Windows XP PCs.
  • We have approx. 3600 user accounts (staff and students)
  • We have a Windows Server 2003 Active Directory and use Windows LDAP services for both Macs and PCs.
  • All staff and student home directories are on stored on our SAN through Windows Servers.
  • DHCP and DNS are both handled by our 2008 Domain Controllers.
  • We had used RIS and WDS for system imaging until this the fall of 2009 when we decided to standardize to DeployStudio.

Major Points:

Both Mac and Windows PC computer name and MAC Address must be entered into OD through WorkGroup Manager. This is necessary for the Windows PC because the automation process below will look at the OD database first.

A major point to know is you will need to add a CNAME record into DNS for theDeployStudio Server. This is important because the PCs will ONLY look for the server by this name. IT MUST BE – deploystudiopcserver and the alias will point to the XServe DNS name you are using for DeployStudio. This is where I stumbled initially so I wanted to emphasize it.

I added options 66 and 67 to our DHCP server main scope. Option 66 will be thefull DNS name of your XServer, and option 67 will be the PXE boot file for DeployStudio which is pxelinux/pxelinux.0.

It is very important to add an IP Helper-Address to the VLAN(S) that you will be imaging on. This helps the workstations see the DeployStudio Server.

In our environment we have one image repository that contains all of our Mac and PC images. You will need to create a few shared folders. NetBootClients0, NetbootSP0, and Images. You will also have to create a local account for DeployStudio service. This account need admin ACL full control privlege of the Images share point. Admin will only need access to the NetBootSP0, and NetBootClients0 share points.

BootCamp and BootPicker are free downloads and needs to be added to the Mac image if you are creating a dual boot image.

 

So how is it done? Let’s start at the beginning!

In the beginning it was dark… No, that’s to far back. Let’s start this at creating a repository, loading DeployStudio Server, and creating a NetBoot set. This is vital to getting the clients to netboot, and in the PC world PXE boot.

Choosing the DeployStudio Server

Your DeployStudio server does not have to be a super, oober-geek, mega-machine. We have a single XServer (outlined above) which is our Wiki, Blog, Podcast Producer, and DeployStudio server. We setup a volume with an Images share point. I will cover the share point and permissions a little later. For now just know you will need a place to put your images, both Mac and Windows. Our average images size is roughly 12 GB for a Mac image (with apps) and 7 GB for a Windows image (no apps). With these image sizes you chew through drive space on your repository server pretty fast.

This is what DeployStudio recommends for server:

  1. •Mac OS X 10.4.11 to 10.6.3
    (Mac OS X server is required for Netboot deployments)
  2. •PXE 2.0 compatible Ethernet cards in your PCs to allow network imaging.
There is some VERY helpful information on the DeployStudio site in their Forums and their Tips page. Any questions or issues that I have had with DeployStudio (and there has not been many knock on wood) I have resolved using the links above. Kudos to the users who posted information here.

Installing DeployStudio Server

I’m not going to spend much time on the actual install. That information can be found here.

What I would like to cover is some of the key points for a successful install.

 

 

 

  • Make sure the DNS name of your server is registered and working in DNS. Use this command in terminal to check the server host name: sudo changeip -checkhostname. Make sure Current HostName and DNS HostName match. If they do not check your DNS cname entry on your DNS server.
  • You need to download and install that last release of DeployStudio on your server.
  • You will need to be logged on as an admin for the install.
  • You will need to create a local user account on the server for the DeployStudio service.
  • Install DeployStudio to the default location.
  • Run DeployStudio Assistant to set to setup the DeployStudio Server.
  • When asked to enter a URL use IP addess format not the fully qualified or DNS name. This will make for a more reliable connection.
  • If SSL connection was chosen during configuration the server URL path will be HTTPS and not HTTP, and the port will be 60443. Here is an example:https://192.168.1.xxx:60443, and the log on account will be the DeployStudio account you setup earlier.

 

Installing DeployStudio PC Server

 

 

 

 

  1. Start DeployStudio Assistant.
  2. When prompted for the DeployStudioPC Server enter the same IP address you used for the DeployStudio server (https://192.168.1.xxx:60443).
  3. The log in will be the same account you used above for DeployStudio.
  4. The Repository URL will be the full path to your Images share point. The cifs prefix allows the PC client to see the Image share point on the Mac server. Example: cifs//<server_ip_address>/images.
  5. The cifs authentication will be the same account you used above.
  6. Save your changes.
  7. We are running DHCP on a Windows Server so we added options 66 and 67 to our DHCP server main scope. Option 66 will be the full DNS name of your XServer, and option 67 will be the PXE boot file for DeployStudio which ispxelinux/pxelinux.0.
  8. DeployStudio PC PXE boot clients must see a DNS entry for the DeployStudio server with the DNS name of deploystudiopcserver, and the alias will point to the XServe DNS name you are using for DeployStudio. This is where I stumbled initially so I wanted to emphasize it.

Something to note – The DeployStudio PC PXE client is a basic Linux PXE client. Nothing cute or graphical about it, but what it lacks in graphics it more than makes up for in performance. It is has the potential of being very fast, depending on your network of course.

 

 

 

 

 

 

Creating a NetBoot Set

Use the newest piece of Mac hardware you have to do this. It SHOULD be backward compatible with your older hardware. You will probably have to create a seperate NetBoot set for your Intel Macs and your Power PC Macs.

 

  1. Start DeployStudio Assistant.
  2. Choose create a DeployStudio NetBoot set.
  3. The System name is a descriptive name. I usually put the DeployStudio release number and Mac OS software version somewhere in this name. Example: DS.1.0.RC17.OS10.6.2
  4. The Unique identified has to be unique per build. The identifiers start at 101 and go up to 65535. I just make sure I add one to the last identifier I used last. Keep it simple.
  5. We increased the time out to 300 seconds (5 minutes) to make sure the systems don’t time out do to latency.
    A .nbi file will be created and should be around 2 GB in size.
  6. Copy this new .nbi file from the location you saved it to a folder on the DeployStudio server called NetBootSP0. This folder should have been created when NetBoot was setup.

 

 

Adding the IP Helper-Address to Your Network

We are very fortunate to have a network infrastructure made up of all Cisco networking equipment. Since we have multipe VLANS it was neccessary to add a IP Helper-Address to the VLAN config on our managed switches. Here is some information on doing that.

  • You will have to telnet into your switch and enter the enable password, enter config mode, and add the line to your vlan ip helper-address xxx.xxx.xxx.xxx
  • Save your config.

So Let’s Connect Some Clients!

The Mac clients are very easy to connect to DeployStudio. Simply boot hold down the “N” key while booting and the workstation will NetBoot to the NetBoot Server and automatically connect to DeployStudio.

 

 

 

 

 

 

Hold the “N” keydown and a grey globe will apprear on the screen. This tells you that NetBoot has been initialized.

 

 

 

 

 

 

Hold down “N” until your see the Apple Logo on top of a smaller spinning globe. You can let go of the “N” key at this point and the system should be booted to the DeployStudio Runtime screen shortly.

 

 

 

 

Somthing to note: You can run DiskUtility from with in the DeployStudio Runtime screen. This is very helpful for modifying system partitions. I have also used DU to create a BootCamp partition for Windows with out touching the master Mac partition. Just dedicate some of free space on the Mac partition to use for the Windows partition.

 

 

 

 

 

The Windows clients are also very easy to connect. Make sure PXE booting is enabled for your network card. For intergrated NICs this is done in BIOS. Once you know PXE booting is enabled boot the computers and press the F12 key immediately after POST. This will give you the boot options menu on most systems. Choose PXE boot and the system should automatically boot to the DeployStudio server.

 

 

 

 

The DeployStudio boot is basically a Linux PXE boot file, after that you should see the following:

 

DeployStudio PC

The DeployStudioTeam

Please press:

– ‘0’ to boot into the local disk(default)

– ‘1’ to boot into maintenance mode

To enter the actual DeployStudio program you will have to choose option 1, or maintenance mode. At this point the Linux PE environment loads (a lot of text scrolls off the screen which is mainly drivers), and then VIOLA, you be brought to the DeployStudio Main Menu. See what I told you, not cute at all, except for the little creatures at the top of the Linux PE screen, and, I have don’t have any idea what they are either.

 

 

 

The DeployStudio PC Main Menu

[1] Restore Boot (default) – this is used to pull a new fresh image down from the server.

[2] Restore Boot (advanced) – This is used if you would like to choose more than one partition

[3] Image Host – This is used to create new master image for the repository on the DeployStudio server.

[4] Restart Host – This is used to (know stay with me on this..) Restart the host!

In my experience you will spend most of you time using option 1, or option 3.

Option 1 will take you to the master image list. This is a list of the PC images found in the /images/masters/PC folder on the repository volume of the DeployStudio Server. Simply arrow down to the image you would like to use and press enter. You will be asked to enter a CAPITAL (upper case) Y to start the imaging process. Keep in mind your are in a Linux PE and it is case sensitive.

Once the imaging process starts a progress screen comes up to show you how the imaging is going.

 

 

 

Preparing the Master Windows Workstation

This process is not major rocket science. We have been prepping and deploying Windows images for decades now. The trick comes in with automating the process. In our case we use key items, Windows Sysprep, and two .vbs scripts that run after the Sysprep answer file runs, actually the last line in the sysprep.inf file starts the first .vbs script. Here is the we use.

  1. Take your model workstation and delete all the local partitions. Use FDISK or something similiar.
  2. Create a new system partition only 50 GB or so. After imaging the remaining disk will show as free space. This allows your older, smaller drives to play along.
  3. Next load Windows fresh
  4. Load all device drivers
  5. Load all Windows Updates
  6. Make any environment modifications. If you wanted the changes to apply to all new profiles create a new local admin profile and make all the system changes you need to, log on as local admin and copy this new profile over the default user profile. This will become the new default user profile and all first time users who log on will get this profile.
  7. Use Windows Sysprep to prepare the workstation for imaging. See detail below.
  8. Now this is where is gets a bit tricky. We worked with software engineer (no, not Choo-Choo Charlie even though he was an engineer) to write two custom .vbs scripts. Here is an exmple of each and what they do. I can’t express enough how vital these are and how much they changed how we image.

Sysprep with a Twist

Use Microsoft Sysprep for Windows XP

  1. Make sure your computer is a member of a workgroup and not a member of the domain.
  2. Type “control userpasswords2” in the Run dialog box. This will bring up the User Accounts properties menu. Disable CTRL+ALT+Delete at log on temporarily. Let the system log onto the desktop as admin to allow the .vbs scripts below to run (Advanced Tab at the top).
  3. Use Sysprep Manager to have the workstation log on as administrator once and run firstboot.vbs file from C:\Windows
  4. Choose “Use Mini Setup” and “Reseal” in Sysprep.

Here is a good example of our sysprep.inf

 

 

Sysprep.Inf Contents – Could be copied and pasted

;SetupMgrTag
[Unattended]
OemSkipEula=Yes
InstallFilesPath=C:\sysprep\i386
TargetPath=\WINDOWS

[GuiUnattended]
AdminPassword=”local_admin_pass”
EncryptedAdminPassword=NO
OEMSkipRegional=1
TimeZone=20
OemSkipWelcome=1

[UserData]
ProductKey=Your_CD_Key
FullName=”Your_Name”
OrgName=”Your_Org”
ComputerName=*

[Display]
BitsPerPel=16
Xresolution=1152
YResolution=864

[Identification]
JoinDomain=your_domain
DomainAdmin=your_admin_account
DomainAdminPassword=your_domain_pass

[Networking]
InstallDefaultComponents=Yes

[Branding]
BrandIEUsingUnattended=Yes

[Proxy]
Proxy_Enable=0
Use_Same_Proxy=0

[GuiRunOnce]
Command0=c:\windows\firstboot.vbs

 

 

 

Firstboot VBS – (firstboot.vbs) Must be placed on root of Windows folder.

Can be copied and pasted into a text document and saved as firstboot.vbs

 

‘ Sysprep firstboot script
‘ Searches AD for a computer account with the current MAC address
‘ If found, rename the computer appropriately, then reboot and bind to AD
‘ If not found, bind to AD with the current name
‘ The machine must be set to autologin for this to work
On Error Resume Next

‘ AD info
domain = “your_domain”
user = “your_admin”
passwd = “your_password”
ou = “ou=Your Computers,dc=your,dc=school,dc=edu”

‘ OD info
odserver = “your_od_server”
odsearchbase = “cn=computers,dc=od_server,dc=dc=your,dc=school,dc=edu”

Const JOIN_DOMAIN = 1
Const ACCT_CREATE = 2
Const ADS_SCOPE_SUBTREE = 2

Set wmi = GetObject(“winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2”)
Set shell = Wscript.CreateObject(“Wscript.Shell”)
‘ Get MAC Address
Set nics = wmi.ExecQuery(“Select * from Win32_NetworkAdapterConfiguration Where IPEnabled = True”)

For Each nic in nics

‘ This line may need to be adjusted to filter out unwanted NICs
‘ such as wireless adapters, etc. The names will vary based
‘ on the hardware & chipset.
If Not Left(nic.Description, 9) = “Bluetooth” and not Left(nic.Description, 16) = “Broadcom 802.11n” Then
macaddr = LCase(nic.MACAddress)
End If
Next
‘ Get name from OD
Set conn = CreateObject(“ADODB.Connection”)
Set cmd = CreateObject(“ADODB.Command”)
conn.Provider = “ADsDSOObject”
conn.Open “Active Directory Provider”
Set cmd.ActiveConnection = conn
cmd.Properties(“Page Size”) = 1000
cmd.Properties(“Searchscope”) = ADS_SCOPE_SUBTREE

cmd.CommandText = “SELECT cn FROM ‘LDAP://” & odserver & “/” & odsearchbase & “‘ WHERE macAddress='” & macaddr & “‘”
Set rs = cmd.Execute

cn = “”
Do Until rs.EOF
cnarr = rs.Fields(0).Value
cn = cnarr(0)
rs.MoveNext
Loop
cn = Replace(cn, “mac”, “pc”, 1, 1)
‘ Rename, bind, & reboot
For Each machine in wmi.InstancesOf(“Win32_ComputerSystem”)
If Not cn = “” Then
machine.Rename(cn)
res = shell.RegWrite(“HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce\sysprep”, “c:\windows\secondboot.vbs”, “REG_SZ”)
shell.Run “shutdown.exe /r /t 0”
Else
res = machine.JoinDomainOrWorkgroup(domain, passwd, domain & “\” & user, NULL, JOIN_DOMAIN+ACCT_CREATE)
shell.Run “shutdown.exe /r /t 0”
End If
Next

Secondboot VBS Must be placed on root of Windows folder. (secondboot.vbs)

Can be copied and pasted into a text document and saved as secondboot.vbs

‘ Sysprep secondboot script
‘ Binds to AD after renaming the machine (in firstboot.vbs)
On Error Resume Next

‘ AD info
domain = “your_domain”
user = “your_admin”
passwd = “your_password”
ou = “ou=Managed Computers,dc=your,dc=school,dc=edu”

Const JOIN_DOMAIN = 1
Const ACCT_CREATE = 2

Set wmi = GetObject(“winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2”)
Set shell = Wscript.CreateObject(“Wscript.Shell”)

‘ Wait 30 seconds for the network to come online
Wscript.Sleep(30000)

‘ Bind, remove the autologin registry key, & reboot
For Each machine in wmi.InstancesOf(“Win32_ComputerSystem”)
res = machine.JoinDomainOrWorkgroup(domain, passwd, domain & “\” & user, NULL, JOIN_DOMAIN+ACCT_CREATE)
shell.RegDelete(“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoAdminLogon”)
shell.Run “shutdown.exe /r /t 0”
Next

Here are the files in .txt format. Save them to C:\Windows folder and change the extension to .vbs , the last line of the Sysprep.inf file will look for them there.

 

 

In a Nutshell

So here is the entire process in a nutshell.

Setup a DeployStudio Server for system imaging and image repository

Setup NetBoot, DHCP, and PXE booting

Add a IP Help-Address that points to your DeployStudio Server to your VLAN

Add a DNS entry for the DeployStudio Server and a CNAME entry for deploystudiopcserver

Load BootPicker on your Mac image

Create a master image for both Mac and Windows

[MACENTERPRISE] Managing Chrome: The Rough Guide

Posted 2012/05/19 By mikep345678

[Editor’s note: This isn’t mine– total props to Nick McSpadden, who posted it to the MacEnterprise mailing list! Thanks, Nick!]

 

Greetings!

This is a sort of follow-up to my guide on managing Firefox, this time focusing on managing Google Chrome.  I’m working on current Chrome version 18 (which just today got updated to 19), and I don’t know for sure how far back this will work, but I think anything higher than v16 properly supports the MCX policies.

The good news about Google Chrome is that it supports MCX!  Unlike Firefox, which requires specific and somewhat obtuse procedures for managing it (including depending upon an add-on that is independently maintained by a hard working individual), the most important parts of Chrome management can be done with already-existing MCX controls.

First let me start off with a link to a very helpful set of information: http://www.chromium.org/administrators
That link covers just about everything you’ll need to know about Chrome policies and management, though some of it is buried.  I discovered (much to my chagrin) that the Chromium site is much more thoroughly documented that Google’s official “Chrome for Administrators” site.

Some important notes about Chrome MCX: all Chrome policies are required to be set to “Always.”  They’re like Profiles from Profile Managers – there’s no middle ground.  Even if you set it to “Once” or “Often,” Chrome will treat the policy as permanent and prevent the user from changing it.  Any policy being managed by MCX in Chrome will be grayed out to user interaction (and there will be a message in the “Options” window about how some settings are being managed by the administrator).  So you’re going to have to “Always” manage these settings whether you like it or not.

The good news is, there’s an alternative, the Master Preferences.  The downside is that the Master Preferences is a “once” option, and doesn’t prevent the user from changing it.  It’s a good way to provide default settings without restricting the users’ ability to personalize it later on.  More on that later.

So, following the Mac Quick Start Guide: (http://www.chromium.org/administrators/mac-quick-start)

1) Inside a fresh copy of Google Chrome is a nice fresh copy of the manifest.  Access it here:
/Applications/Google\ Chrome.app/Contents/Resources/com.google.Chrome.manifest/Contents/Resources/com.google.Chrome.manifest
2) Load this manifest into WGM
3) Here’s the full description of all policies in the Chrome manifest: http://www.chromium.org/administrators/policy-list-3
4) There are some particularly important settings that will be relevant to most.  Here’s what my plist looks like for a lab computer (no individual users):
AutoFillEnabled – False (disables the ability to store autofill information)
BookmarkBarEnabled – True (forces the bookmark bar to show up on all tabs, all the time)
HideWebStorePromo – True (prevents the web store from trying to sell you things, but does not disable the web store)
HomePageIsNewTabPage – False (if you don’t disable this, the homepage will be set to the default Chrome tab page, which opens up the “Most Visited/Apps” switcher)
HomepageLocation – URL (even if you set this, if HomePageIsNewTabPage is set to true, this URL gets ignored)
PasswordManagerEnabled – False (for lab machines, I don’t want them saving passwords, intentionally or accidentally)
RestoreOnStartup – 0 (0 forces it to open the homepage URL on startup)
SyncDisabled – True (same reason as Password Manager – I don’t want these personalized at any time).

That gives you a basic setup for most things you’ll need to worry about.  If you deploy this, you’ll notice a few problems, though.  The first time you launch Chrome, it gives you an undismissable dialogue box asking you if you want to make Chrome the default or submit other info.  That’s bad.  The above manifest also provides no way to control the auto update mechanism, if that’s something you want to do.

This is where the Master Preferences file comes in – http://www.chromium.org/administrators/configuring-other-preferences.  By specifying a Master Preferences file, we can load up default preferences for user accounts *when they are created.*  Note that the Master Preferences file has absolutely no effect on already existing Chrome profiles – only upon new-user generation does Chrome load this file.  It literally copies and pastes the settings in here into the appropriate places in ~/Library/Application Support/Google/Chrome/Default/Preferences.

On Mac OS X, the Master Preferences file must be located at:
/Library/Google/Google Chrome Master Preferences
(yes, really – the file must be named “Google Chrome Master Preferences” with no extension), and must obviously be readable by any user who can launch Chrome (i.e. use 644 permissions).

The Master Preferences file is a JSON file that can contain any of the preferences normally used by Chrome.  If you want the full list of all possible preferences, load up a default Chrome profile and take a look at the Preferences file I mentioned at the path above.  It has everything you’d ever want (and a lot of stuff you probably don’t).  To save you some time, here are some important ones you’ll want to use specifically for deploying Chrome:

{
“homepage_is_newtabpage” : false,
“browser” : {
“show_home_button” : true,
“check_default_browser” : false
},
“bookmark_bar” : {
“show_on_all_tabs” : true
},
“distribution” : {
“skip_first_run_ui” : true,
“show_welcome_page” : false,
“import_bookmarks” : false,
“import_bookmarks_from_file” : “/Library/Google/chrome_bookmarks.html”,
“make_chrome_default” : false
},
“sync_promo” : {
“user_skipped” : true
}
}

The chromium.org page I linked above goes into a bit more detail about this, but I want to give a quick note about the interaction between preferences and MCX.  MCX always wins.  Any policy managed by the MCX and also specified in the Master Prefs will always go the MCX policy.  In the example above, if I had set “homepage_is_newtabpage” to true, it would still be false because MCX sets it to false, and that policy is always enforced.

The really import part is the “distribution” section.  “skip_first_run_ui” will get rid of that annoying dialog box that comes up when you first launch Chrome.  The “import_bookmarks” option asks the user through a UI dialog box if the user wishes to import bookmarks from another browser.  Obviously, we want to suppress that.  There’s an option instead to silently import bookmarks from an HTML file.  You can create this bookmarks HTML file by setting up the bookmarks the way you want, and then Exporting them in the Bookmark Manager.  I place that bookmarks file in /Library/Google/ because it’s already used, but you can put it anywhere.  There is, however, a known bug that has now been assigned a milestone and a solver in Chromium’s bug list – the “import_bookmarks_from_file” is actually ignored if the “skip_first_run_ui” is set to true.  So right now, you can’t silently import your bookmarks in.

The “sync_promo” item doesn’t seem to be necessary if you disable Sync in the MCX settings above, but since MCX policy always wins over Master Prefs, there’s no penalty or downside to including it.

Note that your JSON syntax has to be perfect for this to work.  Any incorrect comma placements, and it simply ignores your master prefs file.  If you find that your Master Prefs isn’t loading up as expected, run Chrome from the Terminal with the debug log turned on to see what’s happening:
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome –enable-logging –v=1
This places a file called “chrome_debug.log” in ~/Library/Application Support/Google/Chrome/Default/ (i.e. default user data directory).  The first line will tell you exactly what went wrong with your Master Prefs file.

Now, there’s still one more problem here: new tabs open up to the default Chrome “New Apps / Most Visited” switcher page (called the newtab page).  Unfortunately for us, there’s no way to change this behavior present in the UI.  The good news is, this behavior annoys plenty of other users, and there are a million extensions you can use to get rid of it.  More good news, is that you can silently include extensions in your MCX manifest!

So simply add this to your MCX settings above (forgive the pseudo XML here, just to indicate type of key):
ExtensionInstallForcelist – <array>
dpjamkmjmigaoobjbekmfgabipmfilij;http://clients2.google.com/service/update2/crx – <string>

This silently forces the install of an extension called “Empty New Tab Page,” and specifies an update URL for it (required, since Chrome autoupdates its extensions too if they come from the Chrome Web Store / Extensions pages).  The extension does what you think it does – you get a blank page.  There are other extensions for customizing the new tab pages, or anything else, so as long as you get the extension ID (it’s the long block of letters in the beginning), you can load whatever you want in here.

There you go!  I’ve tested this using Local MCX on my 10.6 and 10.7 machines, and it works perfectly (deployed through Munki as well).  On the whole, Chrome is a bit easier to manage and deploy than Firefox, just because it doesn’t require modifying the app itself to do this.  Also, the Master Preferences file works for any instance of Google Chrome – even if the users install a copy somewhere other than /Applications.  This also does work for Chromium, the open-source version of Chrome.

Hope this helps someone.


Nick McSpadden
nmcspadden@sacredsf.org
Schools of the Sacred Heart

US Code for Copyright & Fair Use:
http://www.law.cornell.edu/uscode/html/uscode17/usc_sec_17_00000107—-000-.html

_____________________________________________________
MacEnterprise, Inc
http://www.macenterprise.org