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.
I have found that I need to install 4 files to completely control Chrome;
com.google.Chrome.plist 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 Chrome.app"
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/install.py')
keystonePayload = os.path.join(keystoneRegistrationFrameworkPath(), 'Resources/Keystone.tbz')
if os.path.exists(installScript) and os.path.exists(keystonePayload):
retcode = subprocess.call([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 = subprocess.call(ksadminProcess)
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 = subprocess.call(ksadminProcess)
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())
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.
Thanks!
Nick
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?
Reply
Enter your E-mail address. We'll send you an e-mail with instructions to reset your password.