I'm looking for advice on getting homebrew on new employee machines automatically. We have a work flow we would like to keep to as few clicks as possible.
I am trying to get the process of pulling down XCode CLI, installing homebrew, adding cask, and then installing third party apps for new employee machines.
I have the XCode CLI component down but having problems with installing homebrew and adding cask. Curious if anyone has a working script to make this happen. I am deploying this process through self service.
Best answer by jhbush
This may be of some help to you.
#!/bin/bash
# Script to install Homebrew on a Mac.
# Author: richard at richard - purves dot com
# Version: 1.0 - 21st May 2017
# Set up variables and functions here
consoleuser="$(python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "
");')"
brandid="com.application.id"
tn="/path/to/terminal-notifier.app/Contents/MacOS/terminal-notifier"
cd="/path/to/cocoaDialog.app/Contents/MacOS/cocoaDialog"
# Logging stuff starts here
LOGFOLDER="/private/var/log/"
LOG=$LOGFOLDER"Homebrew.log"
if [ ! -d "$LOGFOLDER" ];
then
mkdir $LOGFOLDER
fi
function logme()
{
# Check to see if function has been called correctly
if [ -z "$1" ]
then
echo $( date )" - logme function call error: no text passed to function! Please recheck code!"
echo $( date )" - logme function call error: no text passed to function! Please recheck code!" >> $LOG
exit 1
fi
# Log the passed details
echo -e $( date )" - $1" >> $LOG
echo -e $( date )" - $1"
}
function notify()
{
su -l "$consoleuser" -c " "'"'$tn'"'" -sender "'"'$brandid'"'" -title "'"'$title'"'" -message "'"'$1'"'" "
logme "$1"
}
# Check and start logging - done twice for local log and for JAMF
logme "Homebrew Installation"
# Let's start here by caffinating the mac so it stays awake or bad things happen.
caffeinate -d -i -m -u &
caffeinatepid=$!
logme "Caffinating the mac under process id: $caffeinatepid"
# Have the xcode command line tools been installed?
notify "Checking for Xcode Command Line Tools installation"
check=$( pkgutil --pkgs | grep com.apple.pkg.CLTools_Executables | wc -l | awk '{ print $1 }' )
if [[ "$check" != 1 ]];
then
notify "Installing Xcode Command Tools"
# This temporary file prompts the 'softwareupdate' utility to list the Command Line Tools
touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
clt=$(softwareupdate -l | grep -B 1 -E "Command Line (Developer|Tools)" | awk -F"*" '/^ +\\*/ {print $2}' | sed 's/^ *//' | tail -n1)
softwareupdate -i "$clt"
rm -f /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
/usr/bin/xcode-select --switch /Library/Developer/CommandLineTools
fi
# Is homebrew already installed?
which -s brew
if [[ $? = 1 ]];
then
# Install Homebrew. This doesn't like being run as root so we must do this manually.
notify "Installing Homebrew"
# Curl down the latest tarball and install to /usr/local
curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C /usr/local
# Manually make all the appropriate directories and set permissions
mkdir -p /usr/local/Cellar /usr/local/Homebrew /usr/local/Frameworks /usr/local/bin /usr/local/etc /usr/local/include /usr/local/lib /usr/local/opt /usr/local/sbin /usr/local/share /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var
chown -R $consoleuser /usr/local
chmod g+rwx /usr/local/Cellar /usr/local/Homebrew /usr/local/Frameworks /usr/local/bin /usr/local/etc /usr/local/include /usr/local/lib /usr/local/opt /usr/local/sbin /usr/local/share /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var
chmod 755 /usr/local/share/zsh /usr/local/share/zsh/site-functions
chgrp admin /usr/local/Cellar /usr/local/Homebrew /usr/local/Frameworks /usr/local/bin /usr/local/etc /usr/local/include /usr/local/lib /usr/local/opt /usr/local/sbin /usr/local/share /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var
# Create a system wide cache folder
mkdir -p /Library/Caches/Homebrew
chmod g+rwx /Library/Caches/Homebrew
chown $consoleuser:wheel /Library/Caches/Homebrew
# Install the MD5 checker or the recipes will fail
su -l "$consoleuser" -c "/usr/local/bin/brew install md5sha1sum"
su -l "$consoleuser" -c "echo "'"export PATH=/usr/local/opt/openssl/bin:$PATH"'" >> ~/.bash_profile"
# Remove temporary folder
rm -rf /usr/local/Homebrew
else
# Run an update and quit
notify "Updating Homebrew"
su -l "$consoleuser" -c "/usr/local/bin/brew update" 2>&1 | tee -a ${LOG}
exit 0
fi
# Make sure everything is up to date
notify "Updating Homebrew"
su -l "$consoleuser" -c "/usr/local/bin/brew update" 2>&1 | tee -a ${LOG}
# Notify user that all is completed
notify "Installation complete"
# No more caffeine please. I've a headache.
kill "$caffeinatepid"
exit 0
@sdamiano Unfortunately, with /usr falling under SIP, the script will not work. After found out it broke, we started using @emily 's method since our developers are local admins.
It lets us script out the deployment of xcode cli tools, homebrew, jetbrains apps, and docker with 1 click and 1 password.
#!/bin/sh
#
# Script Name: installHomebrew.sh
# Function: Deploy Homebrew (brew.sh) to the first user added to a new Mac during the post-DEP enrollment SplashBuddy run
# Requirements: DEP, SplashBuddy
#
# Copyright 2018, Route 1337, LLC, All Rights Reserved.
#
# Maintainers:
# - Matthew Ahrenstein: matthew@route1337.com
#
# Contributors:
# - "Dakr-xv": https://github.com/Dakr-xv
#
# See LICENSE
#
# Apple approved way to get the currently logged in user (Thanks to Froger from macadmins.org and https://developer.apple.com/library/content/qa/qa1133/_index.html)
ConsoleUser="$(/usr/bin/python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "
");')"
# Check to see if we have XCode already
checkForXcode=$( pkgutil --pkgs | grep com.apple.pkg.CLTools_Executables | wc -l | awk '{ print $1 }' )
# If XCode is missing we will install the Command Line tools only as that's all Homebrew needs
if [[ "$checkForXcode" != 1 ]];
then
osx_vers=$(sw_vers -productVersion | awk -F "." '{print $2}')
# This temporary file prompts the 'softwareupdate' utility to list the Command Line Tools
touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
# Verify softwareupdate installs only the latest XCode (Original code from https://github.com/rtrouton/rtrouton_scripts)
cmd_line_tools=$(softwareupdate -l | awk '/* Command Line Tools/ { $1=$1;print }' | grep "$osx_vers" | sed 's/^[[ ]]*//;s/[[ ]]*$//;s/*//' | cut -c 2-)
if (( $(grep -c . <<<"$cmd_line_tools") > 1 )); then
cmd_line_tools_output="$cmd_line_tools"
cmd_line_tools=$(printf "$cmd_line_tools_output" | tail -1)
fi
softwareupdate -i "$cmd_line_tools"
rm -f /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
/usr/bin/xcode-select --switch /Library/Developer/CommandLineTools
fi
# Test if Homebrew is installed and install it if it is not
if test ! "$(sudo -u $ConsoleUser which brew)"; then
# Jamf will have to execute all of the directory creation functions Homebrew normally does so we can bypass the need for sudo
/bin/chmod u+rwx /usr/local/bin
/bin/chmod g+rwx /usr/local/bin
/bin/mkdir -p /usr/local/etc /usr/local/include /usr/local/lib /usr/local/sbin /usr/local/share /usr/local/var /usr/local/opt /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var/homebrew /usr/local/var/homebrew/linked /usr/local/Cellar /usr/local/Caskroom /usr/local/Homebrew /usr/local/Frameworks
/bin/chmod 755 /usr/local/share/zsh /usr/local/share/zsh/site-functions
/bin/chmod g+rwx /usr/local/bin /usr/local/etc /usr/local/include /usr/local/lib /usr/local/sbin /usr/local/share /usr/local/var /usr/local/opt /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var/homebrew /usr/local/var/homebrew/linked /usr/local/Cellar /usr/local/Caskroom /usr/local/Homebrew /usr/local/Frameworks
/bin/chmod 755 /usr/local/share/zsh /usr/local/share/zsh/site-functions
/usr/sbin/chown $ConsoleUser /usr/local/bin /usr/local/etc /usr/local/include /usr/local/lib /usr/local/sbin /usr/local/share /usr/local/var /usr/local/opt /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var/homebrew /usr/local/var/homebrew/linked /usr/local/Cellar /usr/local/Caskroom /usr/local/Homebrew /usr/local/Frameworks
/usr/bin/chgrp admin /usr/local/bin /usr/local/etc /usr/local/include /usr/local/lib /usr/local/sbin /usr/local/share /usr/local/var /usr/local/opt /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var/homebrew /usr/local/var/homebrew/linked /usr/local/Cellar /usr/local/Caskroom /usr/local/Homebrew /usr/local/Frameworks
/bin/mkdir -p /Users/$ConsoleUser/Library/Caches/Homebrew
/bin/chmod g+rwx /Users/$ConsoleUser/Library/Caches/Homebrew
/usr/sbin/chown $ConsoleUser /Users/$ConsoleUser/Library/Caches/Homebrew
/bin/mkdir -p /Library/Caches/Homebrew
/bin/chmod g+rwx /Library/Caches/Homebrew
/usr/sbin/chown $ConsoleUser /Library/Caches/Homebrew
# Install Homebrew as the currently logged in user
sudo -H -u $ConsoleUser ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" </dev/null
# If Homebrew is already installed then just echo that it is already installed
else
echo "Homebrew is already installed"
fi
This is ready to use with DEP and any onboarding splash screen app you use, such as Splashbuddy. Also, does work as a Self Service policy!
@igreznik 's script worked well. If your users are non-admins, you have to make them temporary admins to be able to install things or else you will get the following error:
Downloading Command Line Tools (macOS Mojave version 10.14) for Xcode
Downloaded Command Line Tools (macOS Mojave version 10.14) for Xcode
Installing Command Line Tools (macOS Mojave version 10.14) for Xcode
Done with Command Line Tools (macOS Mojave version 10.14) for Xcode
Done.
This script requires the user yourusernamehere to be an Administrator.
Error running script: return code was 1.
Add user to admingroup
sudo dseditgroup -o edit -a $ConsoleUser -t user admin
Remove him afterwards
sudo dseditgroup -o edit -d $ConsoleUser -t user admin
Not the beautiful way to do it, but nobody will notice... :-)
I've been running @igreznik script , with the "add/remove local user to admin group" fix and it has been working well, but recently I get the following error on execution:
Script result: ==> This script will install:
/usr/local/bin/brew
/usr/local/share/doc/homebrew
/usr/local/share/man/man1/brew.1
/usr/local/share/zsh/site-functions/_brew
/usr/local/etc/bash_completion.d/brew
/usr/local/Homebrew
==> The following existing directories will be made group writable:
/usr/local/lib/pkgconfig
==> The following existing directories will have their owner set to neilpalmer:
/usr/local/lib/pkgconfig
==> The following existing directories will have their group set to admin:
/usr/local/lib/pkgconfig
==> /usr/bin/sudo /bin/chmod u+rwx /usr/local/lib/pkgconfig
WARNING: Improper use of the sudo command could lead to data loss
or the deletion of important system files. Please double-check your
typing when using sudo. Type "man sudo" for more information.
To proceed, enter your password, or type Ctrl-C to abort.
sudo: no tty present and no askpass program specified
Failed during: /usr/bin/sudo /bin/chmod u+rwx /usr/local/lib/pkgconfig
Is it possible that something changed in the Homebrew ruby script on github?
This has been working great for me and Is updated to work the Catalina. The only drawback I have run into is because it is not using the ruby install it doesn't set path variables. But for what I use it for doesn't matter
#!/bin/sh
ConsoleUser="$(/usr/bin/python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "
");')"
tempAdminStatus=false
#Check to See if user is an admin or not. Makes the a temporary admin and set tempAdminStatus for removal later
if groups $ConsoleUser | grep -q -w admin;
then
echo "User is an admin"
else
echo "User is not an admin"
echo "Setting as temp admin"
tempAdminStatus=true
dscl . -append /Groups/admin GroupMembership $ConsoleUser
fi
# If XCode is missing we will install the Command Line tools only as that's all Homebrew needs
# Check to see if we have XCode already
# Installing the Xcode command line tools on 10.7.x or higher (Original code from https://github.com/rtrouton/rtrouton_scripts)
checkForXcode=$( pkgutil --pkgs | grep com.apple.pkg.CLTools_Executables | wc -l | awk '{ print $1 }')
# If XCode is missing we will install the Command Line tools only as that's all Homebrew needs
if [[ "$checkForXcode" != 1 ]]; then
echo "Command Line tools are not installed. Will attempt to install."
macos_vers=$(sw_vers -productVersion | awk -F "." '{print $2}')
cmd_line_tools_temp_file="/tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress"
# Installing the latest Xcode command line tools on 10.9.x or higher
if [[ "$macos_vers" -ge 9 ]]; then
# Create the placeholder file which is checked by the softwareupdate tool
# before allowing the installation of the Xcode command line tools.
touch "$cmd_line_tools_temp_file"
# Identify the correct update in the Software Update feed with "Command Line Tools" in the name for the OS version in question.
if [[ "$macos_vers" -ge 15 ]]; then
cmd_line_tools=$(softwareupdate -l | awk '/* Label: Command Line Tools/ { $1=$1;print }' | sed 's/^[[ ]]*//;s/[[ ]]*$//;s/*//' | cut -c 9-)
elif [[ "$macos_vers" -gt 9 ]] && [[ "$macos_vers" -le 14 ]]; then
cmd_line_tools=$(softwareupdate -l | awk '/* Command Line Tools/ { $1=$1;print }' | grep "$macos_vers" | sed 's/^[[ ]]*//;s/[[ ]]*$//;s/*//' | cut -c 2-)
elif [[ "$macos_vers" -eq 9 ]]; then
cmd_line_tools=$(softwareupdate -l | awk '/* Command Line Tools/ { $1=$1;print }' | grep "Mavericks" | sed 's/^[[ ]]*//;s/[[ ]]*$//;s/*//' | cut -c 2-)
fi
# Check to see if the softwareupdate tool has returned more than one Xcode
# command line tool installation option. If it has, use the last one listed
# as that should be the latest Xcode command line tool installer.
if (( $(grep -c . <<<"$cmd_line_tools") > 1 )); then
cmd_line_tools_output="$cmd_line_tools"
cmd_line_tools=$(printf "$cmd_line_tools_output" | tail -1)
fi
#Install the command line tools
softwareupdate -i "$cmd_line_tools" --verbose
# Remove the temp file
if [[ -f "$cmd_line_tools_temp_file" ]]; then
rm "$cmd_line_tools_temp_file"
fi
fi
xcode-select -s /Library/Developer/CommandLineTools
else
echo "Command Lines Tools are already installed"
fi
# Test if Homebrew is installed and install it if it is not
if test ! -f /usr/local/Homebrew/bin/brew ; then
# Jamf will have to execute all of the directory creation functions Homebrew normally does so we can bypass the need for sudo
echo "Creating folder structure for brew and setting correct permissions."
/bin/chmod u+rwx /usr/local/bin
/bin/chmod g+rwx /usr/local/bin
/bin/mkdir -p /usr/local/Homebrew /usr/local/Homebrew/bin /usr/local/Homebrew/etc /usr/local/Homebrew/include /usr/local/Homebrew/lib /usr/local/Homebrew/sbin /usr/local/Homebrew/share /usr/local/Homebrew/var /usr/local/Homebrew/opt /usr/local/Homebrew/share/zsh /usr/local/Homebrew/share/zsh/site-functions /usr/local/Homebrew/var/homebrew /usr/local/Homebrew/var/homebrew/linked /usr/local/Homebrew/Cellar /usr/local/Homebrew/Caskroom /usr/local/Homebrew/Frameworks
/bin/chmod 755 /usr/local/Homebrew/share/zsh /usr/local/Homebrew/share/zsh/site-functions
/bin/chmod g+rwx /usr/local/Homebrew/bin /usr/local/Homebrew/etc /usr/local/Homebrew/include /usr/local/Homebrew/lib /usr/local/Homebrew/sbin /usr/local/Homebrew/share /usr/local/Homebrew/var /usr/local/Homebrew/opt /usr/local/Homebrew/share/zsh /usr/local/Homebrew/share/zsh/site-functions /usr/local/Homebrew/var/homebrew /usr/local/Homebrew/var/homebrew/linked /usr/local/Homebrew/Cellar /usr/local/Homebrew/Caskroom /usr/local/Homebrew /usr/local/Homebrew/Frameworks
/bin/chmod 755 /usr/local/Homebrew/share/zsh /usr/local/Homebrew/share/zsh/site-functions
/usr/sbin/chown $ConsoleUser /usr/local/Homebrew/bin /usr/local/Homebrew/etc /usr/local/Homebrew/include /usr/local/Homebrew/lib /usr/local/Homebrew/sbin /usr/local/Homebrew/share /usr/local/Homebrew/var /usr/local/Homebrew/opt /usr/local/Homebrew/share/zsh /usr/local/Homebrew/share/zsh/site-functions /usr/local/Homebrew/var/homebrew /usr/local/Homebrew/var/homebrew/linked /usr/local/Homebrew/Cellar /usr/local/Homebrew/Caskroom /usr/local/Homebrew /usr/local/Homebrew/Frameworks
/usr/bin/chgrp admin /usr/local/Homebrew/bin /usr/local/Homebrew/etc /usr/local/Homebrew/include /usr/local/Homebrew/lib /usr/local/Homebrew/sbin /usr/local/Homebrew/share /usr/local/Homebrew/var /usr/local/Homebrew/opt /usr/local/Homebrew/share/zsh /usr/local/Homebrew/share/zsh/site-functions /usr/local/Homebrew/var/homebrew /usr/local/Homebrew/var/homebrew/linked /usr/local/Homebrew/Cellar /usr/local/Homebrew/Caskroom /usr/local/Homebrew /usr/local/Homebrew/Frameworks
/bin/mkdir -p /Users/$ConsoleUser/Library/Caches/Homebrew
/bin/chmod g+rwx /Users/$ConsoleUser/Library/Caches/Homebrew
/usr/sbin/chown $ConsoleUser /Users/$ConsoleUser/Library/Caches/Homebrew
/bin/mkdir -p /Library/Caches/Homebrew
/bin/chmod g+rwx /Library/Caches/Homebrew
/usr/sbin/chown $ConsoleUser /Library/Caches/Homebrew
# Install Homebrew as the currently logged in user
echo "Starting Homebrew install"
su $ConsoleUser -c "curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C /usr/local/Homebrew"
# If Homebrew is already installed then just echo that it is already installed
else
echo "Homebrew is already installed"
fi
# Checks tempAdminStatus and removes admin rights if needed.
if [ "$tempAdminStatus" = true ] ; then
dscl . -delete /Groups/admin GroupMembership $ConsoleUser
echo "Admin rights removed"
fi
I've been using the first script posted by @dmarcnw to install during enrollment on Catalina, but I noticed the error below every time I try to use brew.
Error: /usr/local is not writable. You should change the
ownership and permissions of /usr/local back to your
user account:
sudo chown -R $(whoami) /usr/local
Downloading Command Line Tools for Xcode Error downloading Command Line Tools for Xcode: The operation couldn’t be completed. (PKDownloadError error 8.) Done.
Error downloading updates. xcode-select: error: invalid developer directory '/Library/Developer/CommandLineTools' Fri Apr 3 00:28:27 PDT 2020 - Installing Homebrew
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
It looks like an error accessing Github, nothing wrong with the script. Are you under a proxy? Any other networking issues that might cause you to not be able to access it?
SSL_ERROR_SYSCALL
Some I/O error occurred. The OpenSSL error queue may contain more information on the error. If the error queue is empty (i.e. ERR_get_error() returns 0), ret can be used to find out more about the error: If ret == 0, an EOF was observed that violates the protocol. If ret == -1, the underlying BIO reported an I/O error (for socket I/O on Unix systems, consult errno for details).
We use Zscaler for proxy at my work so I have this at the beginning of the install script. It checks for the bash/zsh profiles and then creates them in the users home directory. This lets all the traffic through Terminal pass through the Zscaler app so if your company uses something different for proxy then you would just replace the 'localhost:9000' on my example with your proxy. Good luck!! :)
#!/bin/bash
#Create .bash_profile and .zshrc in users profile directory
log "Creating .bash_profile and .zshrc in users profile directory"
if [[ -f ~/.zshrc ]] ; then
log ".zshrc already exists"
echo "" >> ~/.zshrc
else
log "Creating .zshrc"
touch ~/.zshrc
fi
if [[ -f ~/.bash_profile ]] ; then
log ".bash_profile already exists"
echo "" >> ~/.bash_profile
else
log "Creating .bash_profile"
touch ~/.bash_profile
fi
#Adding proxy settings to files
log "Adding proxy settings for terminal profiles"
echo "#Proxy settings" >> ~/.zshrc
echo export http_proxy=http://localhost:9000 >> ~/.zshrc
echo export https_proxy=http://localhost:9000 >> ~/.zshrc
echo export no_proxy=localhost,127.0.0.1 >> ~/.zshrc
echo "#Proxy settings" >> ~/.bash_profile
echo export http_proxy=http://localhost:9000 >> ~/.bash_profile
echo export https_proxy=http://localhost:9000 >> ~/.bash_profile
echo export no_proxy=localhost,127.0.0.1 >> ~/.bash_profile