How to stop first run messages in Google Chrome

Hi All, this is gonna be another one of those “I had to do something for a client and so I thought I’d share” blogs. You have been warned!
As part of a typical school install, we would need to deploy all applications with the following criteria:

  1. Auto-updates disabled
    • Updates will be managed by whichever system we put in place (typically Munki or Casper), allowing us to vet updates for both issues, and compatibility with each client’s specific site.
  2. Minimal first run messages
    • Including “What’s New”, default application and initial setup screens as we’ve found that these can add an extra distraction, especially to student users and / or using lab Macs.

In this specific case I was looking into a better way to set and / or suppress these items for Google Chrome on OS X.

Previous Methods

One of our previous methods involved packaging up the select contents of ~/Library/Application Support/Google/Chrome/ and deploying this into the user template. *shudder*
With a small amount of free time, I decided to have a look at “A Better Way”. If possible, I wanted a 100% scripted method that didn’t require me to package any files. This would allow me to use the script in multiple scenario’s including templating management solutions.
 

Disabling Auto-updates

This one was easy, we already used a configuration profile from Greg Neagle that disables update checking for both Google Chrome and Google Earth. Criteria 1 resolved!
 

Suppressing default browser check, first runs, and set the Homepage

After a fair bit of research, I found a few pointers to something called a “Master Preferences File”:

This required configuring a Google Preferences file (a JSON file) with the settings I wanted, then deploying this to /Library/Google. New user’s would pull this file as their default settings on first running Google Chrome…
Burns

Master Preferences File

So, like a good little Mac Admin, I created my template file (you can find a copy here if you want one), created a directory called “Google” in /Library and dumped the file inside.
Let’s test this thing out!
Google default
Oh….what?
Everything else I set had skipped fine, except this one thing. Turns out there’s been an open bug for a while on the ‘suppress_first_run_default_browser_prompt’ not being honoured by Google Chrome.
How long?
2 a half years:

Well, that sucks.
 

Fix #1

After some more trial and error, (and, ironically, Googling) I discovered that if an empty file at ~/Library/Application Support/Google/Chrome/First Run exists, this initial first run screen won’t be shown at all. Brilliant!
I wrote a super-basic bash script to create this file, and its directory path, into the logging in User’s home  area and retested.
first launchsecond launch
Oh….what now?
Turns out that not only does that ‘First Run’ file suppress the browser prompts, it also skips the checking for and pulling in of the Master Preferences File.
After more testing and trial and error, I found that I could actually use the Master Preferences File, rename it to just “Preferences” and add it to ~/Library/Application Support/Google/Chrome/Default and it would work.
 

Fix #2

Ok, I got this. So to script this, I will need to complete the following tasks:

  1. Create the folder structure and file in the user’s home at:
    • ~/Library/Application Support/Google/Chrome/First Run
  2. Create the folder structure and file in the user’s home at:
    • ~/Library/Application Support/Google/Chrome/Default/Preferences
  3. Populate the Preferences file with the content I want.

Based on the above requirements, I rewrote some of the bash script to complete the above tasks for the logged in user, with the intention of having the script run at login for each user.
 

But wait…

But then I got thinking. What if I want more flexibility? What if I don’t want to trash any other settings a user may already have configured, but just write the settings I want? What about if I wanted to only set the preferences once, then let the user change them as they wish?
This would all be possible, but would need me to stop treating the Preferences file as a text file, and treat it properly as a JSON file. Which, after discussing with David, was felt was beyond bash and much more of a task for Python.
Now was an opportunity to achieve what I needed, and to take my first crack at Python.

The Final Product

After some testing, I finally managed to get a script that worked and did what I need. You can find a copy here. This script has been designed to be run by root during the login process, or session, of another user.
 
It was written primarily with Casper in mind, allowing you to run it as a policy on the “Login” trigger and specify a custom homepage…
Homepage
 
…and the behaviour (more on this below).
Behaviour
So what does it do?
 

Script Overview

The script follows the following path / logic:

  1. Lines 27-33: Try and collect the values of $3, $4 and $5 from the session (when run from Casper at login, these would correspond to the ‘logging in username’, the value for the Homepage URL and the value for the behaviour, respectively)
  2. Lines 35-37: If $3 is less then 1 character in length (e.g. has no value), pull the logged in user details using the Apple approved method.
  3. Lines 39-43: Try and use this to grab the user’s home folder path. Exit if this cannot be obtained
    1. We don’t want it trying to write to the wrong location.
  4. Lines 45-49: If $4 is less then 1 character in length (e.g. has no value), set the homepage value to “http://www.google.co.uk”.
    1. Feel free to change this as desired.
  5. Lines 51-52: If $5 is less then 1 character in length (e.g. has no value), set the behaviour value to “SKIP”.
    1. More on this later!
  6. Lines 54-59: Set a bunch of variables for file and directory locations
  7. Lines 61-65: Print the discovered values out.
    1. On Casper these will be viewable in the policy logs.
  8. Lines  69-71: Check for the “First Run” file directory, and create it if it doesn’t exist.
  9. Lines 74-78: Try and create the “First Run” file. Exit if this cannot be done.
    1. Without this, the solution will not work, so better to exit then try and soldier on.
  10. Lines 80-85: Try and change the owner of this file and directory to the logged in user. Exit if this cannot be done.
  11. Lines 89-95: Check for the “Preferences” file directory, and create it if it doesn’t exist. Exit if this cannot be done.
  12. Line 97: Check if the “Preferences” file already exists…
    1. Lines 98-100: If it does, and if the behaviour is set to “SKIP”, then exit successfully.
    2. Line 101: If it does, check if the behaviour is set to “UPDATEONCE”…
      1. Line 102: If it is, check if the “run once file” is present…
        1. Lines 103-104: If it is, exit successfully.
        2. Lines 105-106: If not, create it, and skip out of these “If” statements.
      2. Lines 107-108: Check if the behaviour is set to “UPDATE” and continue if so.
    3. Lines 109-115: If the “Preferences” file does not exist, try to create it. Exit if this cannot be done.
  13. Lines 120-124: Try to read the “Preferences” file as a JSON file. If this fails, set the JSON file to contain the top level structure (the curly brackets “{}”)
  14. Lines 128-159: If present, update the specified settings to the desired values, otherwise write them as new values.
  15. Lines 161-163: Write this JSON file back to disk.
  16. Lines 166-170: Try and change the owner of this file and directory to the logged in user. Exit if this cannot be done.

 
Options for behaviour
So this flag will only kick in if the script detects that a Preferences file already exists at
~/Library/Application Support/Google/Chrome/Default/Preferences

  • “SKIP”
    • This will skip any changes to the Preferences file for this user account
  • “UPDATEONCE”
    • This will check for the presence of a file at ~/Library/Application Support/Google/Chrome/Default/PreferencesSetOnce. If one is found, it will skip any changes to the Preferences file for this user account. If one is not found, it will create one, and then make the changes as described above.
    • This acts like a Profile or MCX using a ‘Set-Once’ option
  • “UPDATE”
    • This will also make the changes to the Preferences file as described above.
    • This acts like a Profile or MCX using a ‘Set-Often’ option

 

Usage: Casper

This script has been original written to be used with the Casper Mac Management solution. For this usage, it should be uploaded to the server, and run (with the desired options) by a policy set as:

  • Trigger: Login (only)
  • Frequency: Ongoing

 

Usage: Non-Casper

Although not explicitly tested for it, I can’t see a reason why the script wouldn’t work with a Launch Agent or, more recommended, using Outset.
If you go down this route, you can customise the homepage by editing the value on line 47 and the behaviour by editing the value on line 52.
 

Summary

Well, that one went a little long! I hope at least some of you get some usage out of my first crack at Python. I’m still learning and would love to have any feedback or recommendations!
As always, if you have any questions, queries or comments, let us know below and I’ll try to respond to and delve into as many as I can.
The usual Disclaimer:
While the author has taken care to provide our readers with accurate information, please use your discretion before acting upon information based on the blog post. Amsys will not compensate you in any way whatsoever if you ever happen to suffer a loss/inconvenience/damage because of/while making use of information in this blog.