Remove "Chrome may not be able to keep itself updated" banner without breaking updates

Contributor III

I have a lab of computers I manage that I use a Configuration Profile to manage things like RestoreOnStartupURLs, default browser, PasswordManager, etc. This seems to be causing a yellow banner saying "Google Chrome may not be able to keep itself updated" to pop up on first open for every user. I do make it a point to push out Chrome updates extremely quickly, so I don't mind if Chrome's autoupdate isn't quite working. I do mind if Chrome is showing that banner to every user. Is there a good way to disable this banner without messing with anything major? I don't want to break updates or anything. I just don't want my users pestered and potentially believing they are using an out of date browser because of a banner I can't control.


Contributor II

I have found that I need to install 4 files to completely control Chrome; in /System/Library/User Template/English.lproj/Library/Preferences/

Preferences file in /System/Library/User Template/English.lproj/Library/Application Support/Google/Chrome/Default/

Google Chrome Master Preferences in /Library/Google/

First Run file in /System/Library/User Template/English.lproj/Library/Application Support/Google/Chrome

Configuring with ALL these will end in the Banner not being present. Only using 2-3 of the files will result in configs being ignored or conflicting. Use ALL the 4 files to avoid anguish


Run this right after the update, its working.

**Start add the """ as well


import sys
import os
import getopt
import subprocess
import plistlib

chromePath = "/Applications/Google"
infoPlistPath = os.path.realpath(os.path.join(chromePath, 'Contents/Info.plist'))
brandPath = "/Library/Google/Google Chrome Brand.plist"
brandKey = "KSBrandID"
tagPath = infoPlistPath
tagKey = "KSChannelID"
versionPath = infoPlistPath
versionKey = "KSVersion"

class Usage(Exception): def init(self, msg): self.msg = msg

def chromeIsInstalled(): """Check if Chrome is installed""" if os.path.exists(chromePath): return True else: return False

def chromeVersion(): """Returns Chrome version""" infoPlist = plistlib.readPlist(infoPlistPath) bundleShortVersion = infoPlist["CFBundleShortVersionString"] return bundleShortVersion

def chromeKSUpdateURL(): """Returns KSUpdateURL from Chrome Info.plist""" infoPlist = plistlib.readPlist(infoPlistPath) KSUpdateURL = infoPlist["KSUpdateURL"] return KSUpdateURL

def chromeKSProductID(): """Returns KSProductID from Chrome Info.plist""" infoPlist = plistlib.readPlist(infoPlistPath) KSProductID = infoPlist["KSProductID"] return KSProductID

def keystoneRegistrationFrameworkPath(): """Returns KeystoneRegistration.framework path""" keystoneRegistration = os.path.join(chromePath, 'Contents/Versions') keystoneRegistration = os.path.join(keystoneRegistration, chromeVersion()) keystoneRegistration = os.path.join(keystoneRegistration, 'Google Chrome Framework.framework') keystoneRegistration = os.path.join(keystoneRegistration, 'Frameworks/KeystoneRegistration.framework') return keystoneRegistration

def keystoneInstall(): """Install the current Keystone""" installScript = os.path.join(keystoneRegistrationFrameworkPath(), 'Resources/ksinstall') if not os.path.exists(installScript): installScript = os.path.join(keystoneRegistrationFrameworkPath(), 'Resources/') keystonePayload = os.path.join(keystoneRegistrationFrameworkPath(), 'Resources/Keystone.tbz') if os.path.exists(installScript) and os.path.exists(keystonePayload): retcode =[installScript, '--install', keystonePayload, '--force']) if retcode == 0: return True else: return False else: print >> sys.stderr, "Error: KeystoneRegistration.framework not found" return False

def removeChromeFromKeystone(): """Removes Chrome from Keystone""" ksadmin = "/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/Contents/MacOS/ksadmin" ksadminProcess = [ ksadmin, '--delete', '--productid', chromeKSProductID()] retcode = if retcode == 0: return True else: return False

def registerChromeWithKeystone(): """Registers Chrome with Keystone""" ksadmin = "/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/Contents/MacOS/ksadmin" if os.path.exists(ksadmin): ksadminProcess = [ksadmin, '--register', '--preserve-tttoken', '--productid', chromeKSProductID(), '--version', chromeVersion(), '--xcpath', chromePath, '--url', chromeKSUpdateURL(), '--tag-path', tagPath, '--tag-key', tagKey, '--brand-path', brandPath, '--brand-key', brandKey, '--version-path', versionPath, '--version-key', versionKey] retcode = if retcode == 0: return True else: return False else: print >> sys.stderr, "Error: %s doesn't exist" % ksadmin return False

def main(argv=None): if argv is None: argv = sys.argv try: # Check for root if os.geteuid() != 0: print >> sys.stderr, "This script must be run as root" return 1

if not chromeIsInstalled(): print >> sys.stderr, "Error: Chrome is not installed on this computer" return 1 if keystoneInstall(): print "Keystone installed" else: print >> sys.stderr, "Error: Keystone install failed" return 1 if registerChromeWithKeystone(): print "Registered Chrome with Keystone" return 0 else: print >> sys.stderr, "Error: Failed to register Chrome with Keystone" return 1

except Usage, err: print >>sys.stderr, err.msg print >>sys.stderr, "for help use --help" return 2

if name == "main": sys.exit(main())

New Contributor

Hey Cornoir,

Can you clarify what you mean by installing those files? I just started running into this issue with using a new Google Chrome updating method and would love to squash this.

I'd prefer not to use that Python script because it looks like it invokes the Keystone, which we're trying to remove from the equation completely.


Contributor III

I have a similar issue.
I dont need a fancy solution, I just need to know how to get the Chrome may not be able to keep itself updated banner removed and allow Chrome to auto update for all users, and then provision latest Chrome to all JAMF clients with or without Chrome. I'm hoping to just change a setting file and push that file with the Chrome app.
Any help is greatly appreciated.


How do you scope the prefrences?