Skip to content

Instantly share code, notes, and snippets.

@cabal95
Created October 5, 2015 15:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cabal95/8d528ede367d8539b096 to your computer and use it in GitHub Desktop.
Save cabal95/8d528ede367d8539b096 to your computer and use it in GitHub Desktop.
#!/bin/bash
#
#
# COMPUTER_NAME_MAXLEN - Maximum length the computer name can be. If binding
# to Active Directory this should be 15.
#
# AD_BIND_TO_DOMAIN - If not empty, bind to the given AD domain.
#
# AD_MOBILE - Enable mobile user accounts ('enable' or 'disable').
#
# AD_MOBILE_CONFIRM - Enable the warning for mobile account creation ('enable'
# or 'disable').
#
# AD_LOCAL_HOME - Force home directory to local drive ('enable' or 'disable').
#
# AD_USE_UNC_PATH - Use Windows UNC for network home ('enable' or 'disable').
#
# AD_UNC_PROTOCOL - Set to protocol to use for netowrk home ('afp', 'smb').
#
# AD_MOUNT_HOME - Mount network home as a sharepoint ('enable' or 'disable').
#
# AD_SHELL - Shell to use, 'none' or valid shell (e.g. '/bin/bash').
#
# AD_ADMINS - Active Directory groups whose members can administer this
# computer.
#
# AD_DDNS - List of interfaces to use for dynamic DNS (e.g. 'en0,en1').
#
# MUNKI_MANIFESTS - Array of options to give the user for selecting the
# manifest to use with Munki. If array is empty then no selection is performed.
#
# MUNKI_URL - If non-empty, set the munki SoftwareRepoURL to this value.
#
# SAL_URL - If non-empty, set the Sal ServerURL to this value.
#
# SAL_GROUPS - Array of options to give the user for selecting the group to
# to use with sal. If array is empty then no selection is performed.
#
# MERAKI_ENROLL_URL - Auto-enroll device in Meraki Systems Manager. Use the
# Enrollment URL from the Add Devices page.
#
# USE_MUNKI_BOOTSTRAP - Places a file in /Users/Shared that instructs munki
# to install all packages at the login window automatically. This happens at
# the end of the run and the user is instructed to reboot the computer.
# 'y' means always bootstrap, 'n' means never bootstrap, 'a' means ask.
#
# NTP_SERVER - Network time server to use for this computer.
#
# ENABLE_SSH - If set to 1 enable remote SSH access.
#
# ENABLE_ARD - If set to 1 then enable Apple Remote Desktop access.
#
# SWUPD_URL - If set, set the Apple Software Update URL to this.
#
AD_BIND_TO_DOMAIN=''
AD_MOBILE='enable'
AD_MOBILE_CONFIRM='enable'
AD_LOCAL_HOME='enable'
AD_USE_UNC_PATH='enable'
AD_UNC_PROTOCOL='smb'
AD_MOUNT_HOME='disable'
AD_SHELL='/bin/bash'
AD_ADMINS='Domain Admins,Enterprise Admins'
AD_DDNS='en0,en1,en2,en3,en4,en5,en6,en7'
COMPUTER_NAME_MAXLEN=15
NTP_SERVER='time.apple.com'
ENABLE_SSH=1
ENABLE_ARD=1
SWUPD_URL=''
USE_MUNKI_BOOTSTRAP='a'
MUNKI_URL=''
MUNKI_MANIFESTS=('None:'
'Site Default:site_default')
SAL_URL=''
#SAL_GROUPS=('Org A:9cp5d4bxy6m361foqhwqjyg1iymnl6zxpqbssooydhsilp0vrtkqg2c6lxywryvctb7yher8x791m9bb0icyrfcz52ee4c39cghcpzdqtevec7zgrh5qx7a05ek24v4w'
'Org B:xgywwb9o943hoqtyhd0qdq81hc2ghjga2j52tv31sl9t42lufrbsovi8k1xglu4jkz5w733nnqyrjkm7d5gajs7dvpa0h4ymh1tkgm47yqvv812crfyo7umsac4bt8nv')
MERAKI_ENROLL_URL=''
#####################################################################
#
# You should not need to make any changes below this line.
#
#####################################################################
if [ "$1" != "noclear" ]; then clear; fi
#
# getChoiceFromArray outvar message "${array[@]}"
#
function getChoiceFromArray {
cfa_outVar="${1}"
shift
cfa_msg="${1}"
shift
cfa_options=("${@}")
cfa_sel=0
cfa_count=${#cfa_options[@]}
while [ $cfa_sel -lt 1 -o $cfa_sel -gt $cfa_count ]; do
echo ""
echo "$cfa_msg"
for (( cfa_i=0; cfa_i<${cfa_count}; cfa_i++)); do
cfa_item=${cfa_options[$cfa_i]}
cfa_key=${cfa_item%%:*}
echo $(($cfa_i+1))") $cfa_key"
done
read -p "Choice: " cfa_sel
if [ -z "$cfa_sel" ]; then cfa_sel=0; fi
done
eval "$cfa_outVar=$(($cfa_sel-1))"
}
#
# getValueFromArray outvar index "${array[@]}"
#
function getValueFromArray {
vfa_outVar="${1}"
shift
vfa_idx="${1}"
shift
vfa_options=("${@}")
vfa_item=${vfa_options[$vfa_idx]}
vfa_value=${vfa_item#*:}
eval "$vfa_outVar='$vfa_value'"
}
#
# getKeyFromArray outvar value "${array[@]}"
#
function getKeyFromArray {
kfa_outVar="${1}"
shift
kfa_value="${1}"
shift
kfa_options=("${@}")
kfa_key=''
kfa_count=${#kfa_options[@]}
for (( kfa_i=0; kfa_i<${kfa_count}; kfa_i++)); do
kfa_item=${kfa_options[$kfa_i]}
kfa_k=${kfa_item%%:*}
kfa_v=${kfa_item#*:}
if [ "$kfa_v" == "$kfa_value" ]; then kfa_key="$kfa_k"; fi
done
eval "$kfa_outVar='$kfa_key'"
}
#
# We need to run as root.
#
if [ `whoami` != "root" ]; then
echo "Administrator password may be needed to execute."
echo
sudo "$0" noclear
exit $?
fi
#
# Set time server so the clock is correct.
#
if [ -n "$NTP_SERVER" ]; then
systemsetup -setnetworktimeserver "$NTP_SERVER" >/dev/null || exit $?
fi
#
# Set the computer name if we need to.
#
COMPUTER_NAME=`scutil --get ComputerName`
SET_COMPUTER_NAME=
while [ "$SET_COMPUTER_NAME" != 'y' -a "$SET_COMPUTER_NAME" != 'n' ]; do
echo ""
echo "Computer name is currently $COMPUTER_NAME, do you wish to change it?"
echo "y) Yes"
echo "n) No"
read -p "Choice: " SET_COMPUTER_NAME
if [ "$SET_COMPUTER_NAME" != 'y' -a "$SET_COMPUTER_NAME" != 'n' ]; then
echo "Please select from the choices provided."
fi
done
if [ "$SET_COMPUTER_NAME" = "y" ]; then
echo ""
echo "Please enter the name to be used for this computer."
while true; do
read -p "Computer name: " COMPUTER_NAME
echo ""
REG=`echo "$COMPUTER_NAME" | sed s/[^a-zA-Z0-9\-]//g`
if [ ${#COMPUTER_NAME} -eq 0 ]; then
echo "Computer name too short."
elif [ ${#COMPUTER_NAME} -gt "$COMPUTER_NAME_MAXLEN" ]; then
echo "Computer name must be less than $COMPUTER_NAME_MAXLEN characters."
elif [ ${#COMPUTER_NAME} -ne ${#REG} ]; then
echo "Computer name must contain only letters, numbers and hyphens."
else
break
fi
done
scutil --set ComputerName "$COMPUTER_NAME"
scutil --set LocalHostName "$COMPUTER_NAME"
fi
#
# Bind to Active Directory if requested.
#
if [ -n "$AD_BIND_TO_DOMAIN" ]; then
DO_BIND=1
#
# Check if already bound.
#
BIND_ACCT=`dsconfigad -show | grep '^Computer Account' | cut -c36- | sed 's/\\$//g' | tr '[:upper:]' '[:lower:]'`
LOWER_NAME=`echo "$COMPUTER_NAME" | tr '[:upper:]' '[:lower:]'`
msg=
if [ -n "$BIND_ACCT" -a "$BIND_ACCT" != "$LOWER_NAME" ]; then
msg="Computer is already bound to Active Directory but the computer name does not match (currently $BIND_ACCT). Do you wish to re-bind?"
fi
if [ -n "$BIND_ACCT" -a "$BIND_ACCT" == "$LOWER_NAME" ]; then
msg="Computer is already bound to Active Directory and the computer name matches. Do you wish to re-bind anyway?"
fi
#
# If already bound, let user decide if they want to rebind.
#
if [ -n "$msg" ]; then
CHOICE=
while [ "$CHOICE" != "y" -a "$CHOICE" != "n" ]; do
echo ""
echo "$msg"
echo "y) Yes"
echo "n) No"
read -p "Choice: " CHOICE
done
if [ "$CHOICE" == "n" ]; then
DO_BIND=0
fi
fi
if [ "$DO_BIND" == "1" ]; then
#
# Get AD Username to bind as.
#
BIND_USERNAME=
while [ -z "$BIND_USERNAME" ]; do
echo ""
read -p "Username to bind to Active Directory with: " BIND_USERNAME
done
#
# Unbind if necessary.
#
if [ -n "$BIND_ACCT" ]; then
echo "Computer is already bound to Active Directory. Un-binding first."
dsconfigad -remove -username "$BIND_USERNAME" || exit $?
fi
#
# Perform bind.
#
dsconfigad -add "$AD_BIND_TO_DOMAIN" -username "$BIND_USERNAME" || exit $?
#
# Set AD advanced options.
#
dsconfigad -mobile "$AD_MOBILE" >/dev/null || exit $?
dsconfigad -mobileconfirm "$AD_MOBILE_CONFIRM" >/dev/null || exit $?
dsconfigad -localhome "$AD_LOCAL_HOME" >/dev/null || exit $?
dsconfigad -useuncpath "$AD_USE_UNC_PATH" >/dev/null || exit $?
dsconfigad -protocol "$AD_UNC_PROTOCOL" >/dev/null || exit $?
dsconfigad -sharepoint "$AD_MOUNT_HOME" >/dev/null || exit $?
dsconfigad -shell "$AD_SHELL" >/dev/null || exit $?
dsconfigad -groups "$AD_ADMINS" >/dev/null || exit $?
dsconfigad -restrictDDNS "$AD_DDNS" >/dev/null || exit $?
fi
fi
#
# Enable SSH
#
if [ "$ENABLE_SSH" == 1 ]; then
systemsetup -setremotelogin on >/dev/null || exit $?
fi
#
# Enable ARD
#
if [ "$ENABLE_ARD" == 1 ]; then
/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -activate -configure -allowAccessFor -allUsers -privs -all -access -on -clientopts -setdirlogins -dirlogins yes >/dev/null || exit $?
fi
#
# Set Software Update URL.
#
if [ -n "$SWUPD_URL" ]; then
defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist CatalogURL -string "$SWUPD_URL"
fi
#
# Handle the munki manifest selection.
#
if [ ${#MUNKI_MANIFESTS[@]} -gt 0 ]; then
manifest=`defaults read /Library/Preferences/ManagedInstalls.plist ClientIdentifier 2>/dev/null`
getKeyFromArray current "$manifest" "${MUNKI_MANIFESTS[@]}"
if [ -z "$current" ]; then
msg="Please select the munki manifest to use with this computer:"
else
msg="Please select the munki manifest to use with this computer (currently $current):"
fi
getChoiceFromArray choice "$msg" "${MUNKI_MANIFESTS[@]}"
getValueFromArray value $choice "${MUNKI_MANIFESTS[@]}"
defaults write /Library/Preferences/ManagedInstalls.plist ClientIdentifier -string "$value"
fi
#
# Set sal URL if requested.
#
if [ -n "$SAL_URL" ]; then
defaults write /Library/Preferences/com.grahamgilbert.sal.plist ServerURL -string "$SAL_URL"
fi
#
# Handle the sal group selection.
#
if [ ${#SAL_GROUPS[@]} -gt 0 ]; then
sgroup=`defaults read /Library/Preferences/com.grahamgilbert.sal.plist key 2>/dev/null`
getKeyFromArray current "$sgroup" "${SAL_GROUPS[@]}"
if [ -z "$current" ]; then
msg="Please select the sal group to use with this computer:"
else
msg="Please select the sal group to use with this computer (currently $current):"
fi
getChoiceFromArray choice "$msg" "${SAL_GROUPS[@]}"
getValueFromArray value $choice "${SAL_GROUPS[@]}"
defaults write /Library/Preferences/com.grahamgilbert.sal.plist key -string "$value"
fi
#
# Enroll the device in Meraki if configured.
#
if [ -n "$MERAKI_ENROLL_URL" ]; then
installed=`profiles -L | grep com.meraki`
if [ -z "$installed" ]; then
curl -so /tmp/meraki.mobileconfig -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8) AppleWebKit/535.6.2 (KHTML, like Gecko) Version/5.2 Safari/535.6.2" "$MERAKI_ENROLL_URL"
if [ $? -ne 0 ]; then
echo "Could not retrieve Meraki enrollment profile."
exit 1
fi
profiles -I -F /tmp/meraki.mobileconfig
if [ $? -ne 0 ]; then
echo "Failed to enroll device in Meraki Systems Manager"
exit 1
fi
fi
fi
#
# Set munki repo URL if requested.
#
if [ -n "$MUNKI_URL" ]; then
defaults write /Library/Preferences/ManagedInstalls.plist SoftwareRepoURL -string "$MUNKI_URL"
fi
#
# Initiate the munki bootstrap process if requested.
#
if [ "$USE_MUNKI_BOOTSTRAP" = "a" ]; then
msg='Enable munki bootstrap process?'
CHOICE=
while [ "$CHOICE" != "y" -a "$CHOICE" != "n" ]; do
echo ""
echo "$msg"
echo "y) Yes"
echo "n) No"
read -p "Choice: " CHOICE
done
USE_MUNKI_BOOTSTRAP="$CHOICE"
fi
if [ "$USE_MUNKI_BOOTSTRAP" = "y" ]; then
touch /Users/Shared/.com.googlecode.munki.checkandinstallatstartup
echo ""
echo "Ready for munki bootstrap process. Please reboot computer to finish bootstrap."
fi
@cabal95
Copy link
Author

cabal95 commented Oct 5, 2015

This is a script we use on all new-installs to prep the machine for use. It takes care of a number of repetitive tasks like setting date/time via NTP, joining to Active Directory, enable SSH and ARD, setting the Munki manifest, enrolling in Meraki MDM and finally enabling the Munki Bootstrap process.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment