Install latest version of Google Chrome without re-packaging

cainehorr
Contributor III

Hey everyone...

I wanted to make Google Chrome a part of my automated deployment process and also be available within Self-Service.

Why? Users can just download from Google on their own. True dat. But hey, one-stop shopping in Self-Service, right?

As we all know, Google deploys Chrome via a DMG file. The Google Chrome.app file must be dragged to the /Applications folder.

You could effectively re-package everything using Composer, but then things get REAL STALE, REAL FAST - Google updates Chrome frequently. So stale software is bad software.

So how can we deploy Google Chrome with the freshest of the fresh so we don't get that not-so-fresh feeling?

Well, lemme share my story, morning glory.

.

THE SCRIPT
I wrote a simple script that does the heavy lifting...

I tossed this script into System Settings > Computer Management > Scripts within the JSS...

NOTE: Yes, I am aware that I don't have any error checking taking place. This is v1.1 - quick and dirty. Feel free to add some if you feel the need.

#!/bin/sh

####################################################################################################
#
# Google Chrome Installation Script
#
####################################################################################################
#
# DESCRIPTION
#
# Automatically download and install Google Chrome
#
####################################################################################################
# 
# HISTORY
#
# Created by Caine Hörr on 2016-07-25
#
# v1.1 - 2016-10-11 - Caine Hörr
# Added -nobrowse flag to hdiutil attach /tmp/$VendorDMG command line arguments
# Shout out to Chad Brewer (cbrewer) on JAMFNation for this fix/update
# https://jamfnation.jamfsoftware.com/viewProfile.html?userID=1685
#
# v1.0 - 2016-07-25 - Caine Hörr
# Google Chrome Installation script

# Vendor supplied DMG file
VendorDMG="googlechrome.dmg"

# Download vendor supplied DMG file into /tmp/
curl https://dl.google.com/chrome/mac/stable/GGRO/$VendorDMG -o /tmp/$VendorDMG

# Mount vendor supplied DMG File
hdiutil attach /tmp/$VendorDMG -nobrowse

# Copy contents of vendor supplied DMG file to /Applications/
# Preserve all file attributes and ACLs
cp -pPR /Volumes/Google Chrome/Google Chrome.app /Applications/

# Identify the correct mount point for the vendor supplied DMG file 
GoogleChromeDMG="$(hdiutil info | grep "/Volumes/Google Chrome" | awk '{ print $1 }')"

# Unmount the vendor supplied DMG file
hdiutil detach $GoogleChromeDMG

# Remove the downloaded vendor supplied DMG file
rm -f /tmp/$VendorDMG

.

SMART COMPUTER GROUP
We need a Smart Computer Group so Policy #1 has something to work from...

Computer Group
Display Name = "Google Chrome - Not Installed"
Criteria
[Application Title] [is not] [Google Chrome.app]

.

POLICY #1
This policy makes things happen auto-magically based on the aforementioned Smart Computer Group.

Policy: Options
General
Display Name: "Download & Install Google Chrome"
Enabled = Checked
Triggers = Login, Recurring Check-In, Make Available Offline
Execution Frequency = Ongoing
Make Available Offline = Checked
Scripts
Points to the script in System Settings > Computer Management > Scripts
Priority: After
Maintenance
Update Inventory = Checked

Policy: Scope
Target Computers = Specific Computers
Target Users = Specific Users
Target/Type = "Google Chrome - Not Installed" Smart Computer Group

.

POLICY #2
I wanted a second policy for the sole purpose of Self-Service. I did not want the user's ability to download/install Google Chrome to be hindered within Self-Service by them being out of scope.

Why?

Perhaps the user's version of Chrome isn't updating properly... they can go to Self-Service and download/install at their leisure. There may be other reasons.

Policy: Options
General
Display Name: "Google Chrome (Latest Version)"
Enabled = Checked
Execution Frequency = Ongoing
Make Available Offline = Checked
Scripts
Points to the script in System Settings > Computer Management > Scripts
Priority: After
Maintenance
Update Inventory = Checked

Policy: Scope
Target Computers = All Computers
Target Users = All Users

Policy: Self Service
Make the policy available in Self Service = Checked
Description: Download and install the latest version of Google Chrome
Icon: I ripped the Google Chrome 128x128 icon from the icon file found within the Google Chrome.app
Feature the policy on the main page = Checked

Anyway - That's about it. It's a simple workflow.

  • Chrome will auto-install on machines without Chrome
  • Chrome can be manually installed via Self-Service
  • Chrome will always be fresh when installed

.

Feel free to salt-to-taste - even better if you share your changes.

Cheers!

Kind regards,

Caine Hörr

A reboot a day keeps the admin away!

1 ACCEPTED SOLUTION

cbrewer
Valued Contributor II

If you use

hdiutil attach /tmp/$VendorDMG -nobrowse

it will keep the volume from popping up in Finder.

View solution in original post

94 REPLIES 94

tlarkin
Honored Contributor

@dancunn typically you can install apps over running apps and it will mostly work, but there is always a risk of failure. So, to be safe, you should attempt to quit the app first. I have a script that will quit and run a policy to patch an app using NSRunningApplication and bundle IDs, found here.

Hopefully this helps

stevenjklein
Contributor II

Today I'm revisiting @ellavader 's excellent script. I'm still a huge fan, but…

Today I was troubleshooting some Jamf stuff, and so I was manually invoking a policy that included this script. (using a custom trigger)

And in so doing, was able to "watch" it execute, and noticed this:

installer: Error - the package path specified was invalid: '/tmp/jamf/mount/*.pkg'.

Okay, so the attempt to install as a pkg failed because it wasn't a pkg. Should we care?

We could edit the script to check if the DownloadURL ends with .pkg, or .dmg, or .zip, and only attempt to execute the relevant code.

I'm not a pedant, and I don't want to waste time hiding error messages that no one will see, if it doesn't affect the results.

So, does it matter? Or is worrying about it a waste of time?

achristoforatos
Contributor II

Hello all. I have been happily using the script by @cainehorr It has been working great. However it seems the link for the download no longer works. Does anyone have an updated link to continue using this scipt?

cbrewer
Valued Contributor II

You're using https://dl.google.com/chrome/mac/stable/GGRO/googlechrome.dmg? It works fine for me. What happens if you access it in a browser? Are you getting a valid cert?

achristoforatos
Contributor II

I had an older link which no longer exists. I updated the link and all is well... Thank you! @cbrewer

rhooper
Contributor III

We have this script that goes out once a month and checks the current version to the latest google version. It just went out and started the update to version 78.xxxx. Worked great for us.

!/bin/sh

dmgfile="googlechrome.dmg"
volname="Google Chrome"
logfile="/Library/Logs/GoogleChromeInstallScript.log"

url='https://dl.google.com/chrome/mac/stable/GGRO/googlechrome.dmg'

/bin/echo "--" >> ${logfile}
/bin/echo "date: Downloading latest version." >> ${logfile}
/usr/bin/curl -s -o /tmp/${dmgfile} ${url}
/bin/echo "date: Mounting installer disk image." >> ${logfile}
/usr/bin/hdiutil attach /tmp/${dmgfile} -nobrowse -quiet
/bin/echo "date: Installing..." >> ${logfile}
ditto -rsrc "/Volumes/${volname}/Google Chrome.app" "/Applications/Google Chrome.app"
/bin/sleep 10
/bin/echo "date: Unmounting installer disk image." >> ${logfile}
/usr/bin/hdiutil detach $(/bin/df | /usr/bin/grep "${volname}" | awk '{print $1}') -quiet
/bin/sleep 10
/bin/echo "date: Deleting disk image." >> ${logfile}
/bin/rm /tmp/"${dmgfile}"

exit 0

ralvarezOES
Contributor

Hello. My organization is using this script too (v1.1 at the top of the thread.) But I'm having to reevaluate this because it installs on our MacBooks with auto updates broken. Is anyone having this issue too?

My preference is finding a solution where Chrome is installed with auto updates turned on. Can anyone assist with this?

MrRoboto
Contributor III

We are using a single policy with the following 2 scripts to install the latest version of Chrome, and configure automatic updates...

Install:

#!/bin/sh

dmgfile="googlechrome.dmg"
volname="Google Chrome"
logfile="/Library/Logs/GoogleChromeInstallScript.log"

url='https://dl.google.com/chrome/mac/stable/GGRO/googlechrome.dmg'


/bin/echo "--" >> ${logfile}
/bin/echo "`date`: Downloading latest version." >> ${logfile}
/usr/bin/curl -s -o /tmp/${dmgfile} ${url}
/bin/echo "`date`: Mounting installer disk image." >> ${logfile}
/usr/bin/hdiutil attach /tmp/${dmgfile} -nobrowse -quiet
/bin/echo "`date`: Installing..." >> ${logfile}
ditto -rsrc "/Volumes/${volname}/Google Chrome.app" "/Applications/Google Chrome.app"
/bin/sleep 10
/bin/echo "`date`: Unmounting installer disk image." >> ${logfile}
/usr/bin/hdiutil detach $(/bin/df | /usr/bin/grep "${volname}" | awk '{print $1}') -quiet
/bin/sleep 10
/bin/echo "`date`: Deleting disk image." >> ${logfile}
/bin/rm /tmp/"${dmgfile}"

exit 0

Updates:
https://github.com/ryangball/chrome-enable-autoupdates/blob/master/chrome-enable-autoupdates.sh

ralvarezOES
Contributor

MrRoboto, your script on Github totally worked for me. Automatic updates in Chrome are working. Thanks a million.

Dylan_YYC
Contributor III

When i run the Github script i get the following, am i doing something wrong?
Keystone installed
AutoUpdateChrome.sh: line 51: /Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/Contents/MacOS/ksadmin: No such file or directory
Error: Failed to register Chrome with Keystone - code 0

MrRoboto
Contributor III

@ralvarezOES That's good to hear. It's not my script, created by @ryan.ball

@Dylan_YYC What version of Chrome are you testing? The script only works for 75+

Dylan_YYC
Contributor III

@MrRoboto im testing on ver 79

MrRoboto
Contributor III

@Dylan_YYC I tested on a 10.14.6 Mac, deleted Google Chrome.app and /Library/Google folder. Then ran the install and autoupdate scripts via a Self Service policy and it works okay... How are you running the autoupdate script, via Terminal?

[STEP 1 of 5]
Executing Policy Google Chrome
[STEP 2 of 5]
Running script Chrome-Install...
Script exit code: 0
Script result:
[STEP 3 of 5]
Running script chrome-enable-autoupdates-v2...
Script exit code: 0
Script result: Keystone installed
Registered Chrome with Keystone
[STEP 4 of 5]
[STEP 5 of 5]

ryan_ball
Valued Contributor

By the way, if anybody ever has an issue with the script below, please create an issue or PR. You might see something before I do.
https://github.com/ryangball/chrome-enable-autoupdates/blob/master/chrome-enable-autoupdates.sh

tlarkin
Honored Contributor

Just a friendly reminder, AutoPKG can do this and everyone should at least give it a try

dancunn
New Contributor II

hey everyone, i am using the 2 scripts mentioned here to download and install chrome and force enable auto updates successfully on most machines. however, it fails on some machines and jamf log shows the following error:

Script result: ditto: can't get real path for source '/tmp/chrome.mpuP/Google Chrome.app'<br/>hdiutil: detach failed - No such file or directory<br/>2020-01-21 13:13:57.034 defaults[5246:31053] <br/>The domain/default pair of (/Applications/Google Chrome.app/Contents/Info.plist, CFBundleShortVersionString) does not exist<br/>2020-01-21 13:13:57.055 defaults[5249:31061] <br/>The domain/default pair of (/Applications/Google Chrome.app/Contents/Info.plist, KSUpdateURL) does not exist<br/>2020-01-21 13:13:57.072 defaults[5250:31065] <br/>The domain/default pair of (/Applications/Google Chrome.app/Contents/Info.plist, KSProductID) does not exist<br/>Error: KeystoneRegistration.framework not found<br/>

Looks like its failing to mount the dmg in the temp directory and so then can't find the expected path when it tries to copy it to Applications. Anyone know why this might happen?

Frances_R
New Contributor II

Does anyone have any recommendations as to politely nudging the user to quit Chrome so it can update? I'm running a script similar to the one posted by @lbr but it's failing on every single machine because everyone has Chrome open.

chris_hansen
Contributor

@lfrances Take a look at https://support.google.com/chrome/a/answer/7679871?hl=en

com.google.Keystone.plist I think is the file to manage.

ryan_mccullough
New Contributor

@dancunn - Having the same issue. Wondering if it is related to Catalina. Did you ever figure this out?

johankjellman
New Contributor II

Change the URL to https://dl.google.com/chrome/mac/universal/stable/GGRO/ to download the Universal that works on both Intel and Apple Silicon

cainehorr
Contributor III

WOW - I haven't checked in on this thread (or this script) in such a very long time. I am... AMAZED... at how much interest and inspiration there's been since my original post so long ago! Very cool!

Kind regards,

Caine Hörr

A reboot a day keeps the admin away!

KyleEricson
Valued Contributor II

@cainehorr @ellavader Do you all want to add this script to Github so we can track issues and features with it?
I'd be happy to do this too if you want.
Universal App Installer Script
I use this script a lot and would love to see it maintained and updated.

Read My Blog: https://www.ericsontech.com

vmalapati_mu
New Contributor III

Hey guys,
Is there a change in URL to download Chrome Enterprise using curl? Here is the old one that I have been using so far. url='https://dl.google.com/chrome/mac/stable/gcem/GoogleChrome.pkg'
/usr/bin/curl -s -o /tmp/${pkgfile} ${url}

Also is there a way to differentiate Chrome Enterprise and legacy browser?

Thanks & Regards
VM

FrogOnABike
New Contributor II

Just a small update on my side as I'd been testing this script on some new M1 based machines.
Initially, I was a little confused as it "appeared" to work according to Jamf policy logs in the web portal but I wasn't see Chrome appear in the apps folder.

I tested the commands on my own machine and it appeared to download OK and the expected files appeared as per the set variables.

I then tried following more of the steps on my actual test machine and noticed that when I executed the step to copy the .app file from the mounted dmg > Applications folder it was taking a bit longer than the sleep period of 10 in this script so I bumped it to 15 and that seems to have helped.

I can only assume the app is getting a bit bigger and 10s isn't quite long enough to copy it now :)

austin_nill
New Contributor II
#!/bin/sh

pkgfile="googlechrome.pkg"
logfile="/Library/Logs/GoogleChromeInstallScript.log"

url='https://dl.google.com/chrome/mac/universal/stable/gcem/GoogleChrome.pkg'


/bin/echo "--" >> ${logfile}
/bin/echo "`date`: Downloading latest version." >> ${logfile}
/usr/bin/curl -s -o /tmp/${pkgfile} ${url}
/bin/echo "`date`: Installing pkg." >> ${logfile}
installer -pkg /tmp/${pkgfile} -target /


exit 0

Small changes I made for an Apple Silicon version of the script. Main problem is that the universalbinary installer is a pkg, or at least the url I was using was a pkg. I just removed the dmg related lines and replaced them with an installer command.

Geissbuhler
Contributor

Just made this script that looks for Architecture and grabs the appropriate install, and Removes the "This was downloaded from the internet warning":

 

#!/bin/zsh

# make temp folder for downloads
mkdir "/tmp/googlechrome"

# change working directory
cd "/tmp/googlechrome"

# Download Correct Google Chrome based on Architecture
 
arch_name="$(uname -m)"
 
if [ "${arch_name}" = "x86_64" ]; 
then 
curl -L -o "/tmp/googlechrome/Googlechrome.dmg" "https://dl.google.com/chrome/mac/stable/GGRO/Googlechrome.dmg"
elif [ "${arch_name}" = "arm64" ]; 
then curl -L -o "/tmp/googlechrome/Googlechrome.dmg" "https://dl.google.com/chrome/mac/universal/stable/GGRO/googlechrome.dmg"
fi

# Mount the DMG
hdiutil attach Googlechrome.dmg -nobrowse

# Install Google Chrome
cp -r /Volumes/Google\ Chrome/*app /Applications

#Tidy Up
hdiutil unmount "/Volumes/Google Chrome"
sleep 5
sudo rm -rf "/tmp/googlechrome"
sleep 5

#Bless Google Chrome app
xattr -rc "/Applications/Google Chrome.app"

 

 

virtasupport
New Contributor II

This still grabs the old 98.0 version

virtasupport
New Contributor II

All of these scrips grab an extremely old version

JasonAtCSUMB
Contributor

I prefer this method, which uses Google's signed pkg to install, thus avoiding a lot of other pitfalls.

https://github.com/jfiliceatcsumb/Scripts/blob/19ea2a7a27a89f4eed6944acfa3db093aab66239/Google_Chrom...

As of today, it installs version 103.0.5060.114 (5060.114).

 

As shown in Suspicious Package, this also includes the universal binary version of Chrome.

Screen Shot 2022-07-12 at 2.29.20 PM.png

scottlnrd
New Contributor III

The correct way to get the most current Google Chrome pkg file, is to follow the directions from this Google KB directly. https://support.google.com/chrome/a/answer/9915669?hl=en

scottlnrd
New Contributor III

I have also refined the script that @ellavader  originally released for installing from any available download location. (https://www.jamf.com/jamf-nation/discussions/20894) But note that from my testing, I had to change it from just a download link, to the whole curl command in order to work in certain scenarios, giving a little added flexibility. 

#!/bin/sh

# -------------------------------------------------------------------------------------
#
# Universal App Installer Script
#
# -------------------------------------------------------------------------------------
#
# DESCRIPTION
#
# Automatically download and install nearly any app from a direct download link
# App can be packaged as .dmg, .pkg, or .zip, and have either the .app or a .pkg inside
#
# -------------------------------------------------------------------------------------
#
# HISTORY
#
# Created by Ella Hansen on 10/30/2018
#
# v2.0 - 08/31/2022 - Scott Leonard
# Created script based on Caine Hörr's script for Google Chrome:
# https://www.jamf.com/jamf-nation/discussions/20894
#
# -------------------------------------------------------------------------------------

# ADD THE DIRECT DOWNLOAD LINK FOR YOUR APP HERE INCLUDING THE Curl COMMAND, WITH OPTIONS:
# Example: curl --location DownloadURL="https://dl.google.com/chrome/mac/stable/googlechrome.dmg" --output Chrome.dmg
DownloadURL="$4"

# -------------------------------------------------------------------------------------
# LEAVE THIS CODE ALONE:

# Create directory /tmp/jamf, continue if directory already exists
mkdir /tmp/jamf || :

# Change directory to /tmp/jamf
cd /tmp/jamf

#Download installer container into /tmp/jamf
$DownloadURL

# Make directory to move and copy .app from
mkdir /tmp/jamf/mount

# Unzip installer container and place contents into /tmp/jamf/mount, continue on error
find /tmp/jamf -name "*.zip" -exec unzip {} -d /tmp/jamf/mount \; ||

# Uncompress or Extract Tar file
find /tmp/jamf -name "*.bz2" -exec tar -xf {} -C /tmp/jamf/mount \; || :

# If container is a .dmg:
# Mount installer container
# -nobrowse to hide the mounted .dmg
# -noverify to skip .dmg verification
# -mountpoint to specify mount point
find /tmp/jamf -name "*.dmg" -exec sh -c "yes | hdiutil attach {} -nobrowse -noverify -mountpoint /tmp/jamf/mount" \; || :

# Copy the .app file from the installer container to /Applications
# Preserve all file attributes and ACLs
cp -a /tmp/jamf/mount/*.app /Applications || :

# If container is a .pkg
# Run installer package with the boot drive as the destination
find /tmp/jamf -name "*.pkg" -exec installer -pkg {} -target / \; || :

# Unmount the secondary installation folder, continue on error
hdiutil detach /tmp/jamf/mount || :

# Delete the main installation folder
rm -r /tmp/jamf

scottlnrd
New Contributor III

Corrected the example with better explanation in the comments.

#!/bin/sh

# -------------------------------------------------------------------------------------
#
# Universal App Installer Script
#
# -------------------------------------------------------------------------------------
#
# DESCRIPTION
#
# Automatically download and install nearly any app from a direct download link
# App can be packaged as .dmg, .pkg, or .zip, and have either the .app or a .pkg inside
#
# -------------------------------------------------------------------------------------
#
# HISTORY
#
# Created by Ella Hansen on 10/30/2018
#
# v2.0 - 08/31/2022 - Scott Leonard
# Created script based on Caine Hörr's script for Google Chrome:
# https://www.jamf.com/jamf-nation/discussions/20894
#
# -------------------------------------------------------------------------------------

# ADD THE DIRECT DOWNLOAD LINK FOR YOUR APP HERE INCLUDING THE CURL COMMAND, WITH OPTIONS IN THE PARAMETER 4 LOCATION IN THE JAMF POLICY:
# Example: curl --location https://dl.google.com/chrome/mac/stable/googlechrome.dmg --output Chrome.dmg
DownloadURL="$4"

# -------------------------------------------------------------------------------------
# LEAVE THIS CODE ALONE:

# Create directory /tmp/jamf, continue if directory already exists
mkdir /tmp/jamf || :

# Change directory to /tmp/jamf
cd /tmp/jamf

#Download installer container into /tmp/jamf
$DownloadURL

# Make directory to move and copy .app from
mkdir /tmp/jamf/mount

# Unzip installer container and place contents into /tmp/jamf/mount, continue on error
find /tmp/jamf -name "*.zip" -exec unzip {} -d /tmp/jamf/mount \; ||

# Uncompress or Extract Tar file
find /tmp/jamf -name "*.bz2" -exec tar -xf {} -C /tmp/jamf/mount \; || :

# If container is a .dmg:
# Mount installer container
# -nobrowse to hide the mounted .dmg
# -noverify to skip .dmg verification
# -mountpoint to specify mount point
find /tmp/jamf -name "*.dmg" -exec sh -c "yes | hdiutil attach {} -nobrowse -noverify -mountpoint /tmp/jamf/mount" \; || :

# Copy the .app file from the installer container to /Applications
# Preserve all file attributes and ACLs
cp -a /tmp/jamf/mount/*.app /Applications || :

# If container is a .pkg
# Run installer package with the boot drive as the destination
find /tmp/jamf -name "*.pkg" -exec installer -pkg {} -target / \; || :

# Unmount the secondary installation folder, continue on error
hdiutil detach /tmp/jamf/mount || :

# Delete the main installation folder
rm -r /tmp/jamf

 

This post has only 1 Kudo, from me.

C'mon, my fellow Jamfers.  If you've used this script, click the 👍 button above! 

I've used multiple versions of this script over the years, and I appreciate all those who contributed to it over the years: 

  1. Caine Hörr
  2. Ella Hansen
  3. Scott Leonard

Show them some appreciate!

sdagley
Esteemed Contributor II

@stevenjklein No question that an example script on how to install apps only distributed via a .dmg is useful, but when it comes to Chrome this is now the wrong solution because Google provides a .pkg installer for Enterprise environments: https://chromeenterprise.google/browser/download/#mac-tab

MazharHusain
New Contributor

#!/bin/zsh

# Changed the installer from .dmg to .pkg and took out the bit for choosing an architecture.

# make temp folder for downloads

mkdir "/tmp/googlechrome"

# change working directory

cd "/tmp/googlechrome"

# Download Google Chrome

 

curl -L -o "/tmp/googlechrome/googlechrome.pkg" "https://dl.google.com/chrome/mac/universal/stable/gcem/GoogleChrome.pkg"

 

# Install Google Chrome

sudo /usr/sbin/installer -pkg googlechrome.pkg -target /

#Tidy Up

sudo rm -rf "/tmp/googlechrome"

#Bless Google Chrome app

xattr -rc "/Applications/Google Chrome.app"

stevenjklein
Contributor II

@ellavader @cainehorr 

I've been using this script for over a year, with much success, but now I've come across a URL that breaks it.

The URL for the Apple Silicon zoom client is this:

https://zoom.us/client/latest/Zoom.pkg?archType=arm64

The script expects the downloaded file to end in .pkg, and since this one doesn't. it fails to install.

I could modify the script to treat this URL as a special case, but I'd prefer to modify it to work with any pkg download where the filename doesn't end in .pkg.

Any suggestions?

 

Instead of using curl on endpoints which can easily be used maliciously by spoofing DNS, might I suggest using something like autopkg? or Installomator? That have security measures in place to help verify what's being downloaded.

scottlnrd
New Contributor III

Autopkg is great until it isn't. I've had it create more issues than it solved unfortunately. 

Downloads a pkg for me. If you have a look at the script I modified, near the bottom of this thread, I re-engineered it to accept pretty much any file, to include pkg, dmg, zip, etc.