Although this is technically a blog, it's primary content is a series of articles on how to get Firefox working in a corporate Windows environment. Later ones build on earlier ones, so you might want to use the Table of Contents on the right to read through it chronologically instead of reading straight down from here.

Upgrading to Firefox 9

I've updated the site for everything you need to do to push out Firefox 9.  Here's a summary of the changes for those of you who have already followed these instructions for Firefox 4:
  • FrontMotion has stopped including Flash with their Firefox MSIs, so tweaking our custom version with Orca got simpler.
  • The XMarks extension needs to be updated to work with version 9, so I updated that post with the slight changes required for XMarks 4.0.5.
  • The PlainOldFavorites extension no longer works from C:\Program Files, it must be installed in the user profile folder.  I updated my login script to allow you to specify extensions where that's the case and it will copy them over to the profile for you.
  • I switched from IE Tab Plus to IE Tab v2, which requires slightly different settings but allows the rule variable to be the same.  The script was updated to support them both from the same ieTabRules variable.
  • New versions of Firefox ask users if they really want all the extensions that are installed, plus they treat extensions installed via the registry as suspicious and ask the user about those too.  Since that affects the extensions we're pushing out via MSI I documented what you need to do to disable it.
  • I documented a few other Firefox settings you may want just to prevent it from popping up some unnecessary notices.

Additional Useful Firefox Settings

Preventing Custom Extensions from Being Disabled

Newer versions of Firefox are trying to clean up unwanted extensions.  Anything that tries to install itself automatically will cause Firefox to prompt the user to make sure they really want it.  Great for consumers, bad for us when we're pushing out extensions centrally.  We don't want our users to disable something important, nor do we want to hassle them with a prompt they may not know how to respond to.  Fortunately we're also pushing out configurations via my script so we can disable this.  These are the settings you need to add to firefoxSettings:
var firefoxSettings = new Array
    "extensions.shownSelectionUI", true,
    "extensions.autoDisableScopes", 0
    );
The first one prevents the "Select Your Add-Ons" window that pops up the first time you use a more recent version of Firefox.  That asks the user if they really want to keep everything that's already installed, so we make it go away by marking it as already having been shown.  The second setting prevents Firefox from viewing extensions installed via the registry as suspicious and prompting the user about them, which is what we want since this is what we use to add our MSI extensions to Firefox.  With both these settings Firefox should continue to work quietly.


Preventing Other Unnecessary Prompts

These aren't strictly necessary, but for all their good intentions we just rather not have Firefox hassling our users with prompts.
var firefoxSettings = new Array(
    "toolkit.telemetry.prompted", 2,
    "toolkit.telemtry.rejected", true,
    "browser.rights.3.shown", true
    );
The first two prevent the "improve Firefox by sending anonymous information about performance etc." banner and says no.  The third prevents the "know your rights" banner.  Nothing malicious about either of these, we just want Firefox to be quiet and Just Work in a corporate environment.  You can leave them enabled if you wish.


Opening Local Files

So you have an intranet which has links to files on a share drive using the file: protocol, like file:///G:/Company Policy.doc.  Internet Explorer opens these files fine, but Firefox does nothing.  You could add your intranet to IE Tab if you wanted to, but there should be a way to make Firefox do this right?  No need to switch out browser engines unnecessarily right?  There is:
If you're using my script, add these three lines to firefoxSettings:
var firefoxSettings = new Array(
    "capability.policy.policynames", "localfilelinks",
    "capability.policy.localfilelinks.sites", "http://intranet",
    "capability.policy.localfilelinks.checkloaduri.enabled", "allAccess"
    );
Change http://intranet to your own URL.  localfilelinks.sites is a space separated list so you can have more than one if you need them.


Disabling the Built-In PDF Viewer

Firefox comes with a built-in PDF viewer starting with version 19.  If that works for you, great!  One less plug-in to worry about and one less attack vector.  However, if you need the full functionality of Adobe Reader you can disable it with this setting:
var firefoxSettings = new Array(
    "pdfjs.disabled", true
    );


Disabling the New Version Home Page

The first time you open Firefox after an update it opens a special home page.  Sometimes it's an About Firefox type page which you may want to suppress just to not bother the user, and sometimes it tells you Firefox is out of date which isn't something the user can do anything about.  This is also an issue because the Firefox MSIs can lag behind the official releases, so the newest one available to you is still considered old by the system.  This setting disables the special home page:
var firefoxSettings = new Array(
    "browser.startup.homepage_override.mstone", "ignore"
    );


Per-User or Per-Computer Settings

Sometimes you need to push out a particular setting per-user or per-computer.  For example, I turn off Firefox's smooth scrolling feature on our remote desktop server as it would cause too many unnecessary screen updates.  You can do it by adding code like this under the firefoxSetting variable in the login script:
if (computerName == "rdservername")
    {  firefoxSettings.push("general.smoothScroll", false);  }
You can also put userName instead of computerName.  The script was updated in July 2012 to provide the computerName variable, so if you have an older version you can just add this line to the top:
var computerName = network.ComputerName.toLowerCase();


Combining Multiple Settings

I hope it's obvious, but just in case it's not, when you're combining multiple settings from this blog you're not assigning a new array to firefoxSettings every time, you're merging them into one.  So to apply both the custom extensions settings and the local files settings, it would look like this:
var firefoxSettings = new Array(
    "extensions.shownSelectionUI", true,
    "extensions.autoDisableScopes", 0,
    "capability.policy.policynames", "localfilelinks",
    "capability.policy.localfilelinks.sites", "http://intranet",
    "capability.policy.localfilelinks.checkloaduri.enabled", "allAccess"
    );
There's an extra comma added after 0 to continue the list and then it goes straight into the second set of values.  If you had multiple "firefoxSettings = new Array(" statements the later ones would simply overwrite the earlier ones.

Dealing With Those Pesky IE-Only Sites (IE Tab v2)

Last updated October 2016
(This is instructions for using IE Tab v2.  For IE Tab Plus and IE View, go here.)

Sadly, even in this day in age there are still a few IE-only sites I have to deal with.  However, we can use the IE Tab v2 extension to manage this problem.  It uses Internet Explorer to render pages in a tab that looks like any other Firefox tab.  It's transparent to the end user.  You just need to specify which sites it should be done for via my login script.


Configuring IE Tab v2

You should add these lines to firefoxSettings in the login script:
var firefoxSettings = new Array(
   "extensions.ietab2.filter", true,
   "extensions.ietab2.compatMode", "ie8mode",
   "extensions.ietab2.hasRun", true
   );
The first setting makes sure it's enabled.  The second setting tells it to render pages in IE8 Standards Mode, since it uses IE7 by default and there's no reason you should be using that.  There's also an IE9 mode if you have that installed, but 8 is the highest version available for Windows XP.  The third setting helps prevent it from opening a welcome tab the first time it's used, but it also requires an edit to be effective.

When you first use this extension it will pop up a changelog, which I think would be annoying and/or confusing for end users.  If that's not a huge deal for you you can package this extension as a MSI without any edits and push it out.  If you want to go the extra mile you can remove the line of code that does that, but it requires getting the edited extension signed before it can be used on Firefox 48 and later.

If you're willing to do that, edit chrome\content\ietabOverlay.js and find and delete this line:
gIeTab2.checkShowIntro(); 
Then follow the rest of the instructions here to get it signed before packaging it into a MSI.

In the login script there's a variable called ieTabRules which is where you put the regular expressions that determine which sites get opened in an IE tab.  Add entries like below.  Because they're regular expressions you have to include asterisks at the end.
var ieTabRules = new Array(
   "http://*update.microsoft.com/*",
   "http://www.windowsupdate.com/*"
   );
If you want to configure any other settings go to about:config in your browser, look at what's available under extensions.ietab2, and add what you want to firefoxSettings.

Tweaking the Firefox MSI

(The screen shots in this post say Firefox 9.0.1 but these instructions still apply with Firefox 14-16)

So you downloaded the Firefox MSI but you don't like how it installs.  Maybe you don't want Firefox to become the default browser because you have IE-dependent software and it should only be an option.  Well we can fix that.
The first thing you need is Orca, a tool from Microsoft to create MSI transforms.  It's not the most user friendly thing but I'll walk you through it.  Yeah, that link is to someone's blog post, but as it says to get it direct from Microsoft you're going to have to download it as part of a big SDK.

Got it?  Good.  Fire it up and open your Firefox MSI.  We don't want to edit it directly so immediately after opening it go to Transform > New Transform.  Your changes will now be highlighted in green and put in a transform file instead.


Choosing Which Features to Install

First we have to go to the Feature section.  FrontMotion stopped including Flash in the MSI so we don't have to worry about that anymore.  Instead we can just see that the Level property is 3 to just install Firefox and 4 to also make it the default browser.

If we go to the Property section we can see INSTALLLEVEL defaults to 3.  If you don't want Firefox to be the default browser you can leave it alone, or if you do you can double click it and change it to 4.

Shortcuts

If you want to you can customize the shortcuts as well.  FrontMotion now makes the desktop icon a regular shortcut instead of a special one governed by the registry, so we only need to deal with the Shortcuts section.  If you don't want the desktop icon to be created, just right click on DesktopFolder and select Drop Row.

If you want the Start menu icon to appear directly in Program Files instead of having the unnecessary Firefox subfolder, change the Directory property from _PROGRAMMENUFOLDER_MOZILLA_FIREFOX to ProgramMenuFolder.

Finishing Up

Now that we have the tweaks we want, go to Transform > Generate Transform.  This will create a MST file you can use with your MSI.

To apply it in Active Directory, make sure you choose Advanced when creating a new package.


Then add the MST on the Modifications tab.  You won't be able to do this after the package is created.

That's it.  You now have a customized Firefox install via Active Directory.


Previous versions of this post:

AutoConfiguring XMarks for the Logged In User (4.0.5-4.1.3)

(These are the instructions for Firefox 9.0.1 and XMarks 4.0.5, but they still apply with Firefox 14-16 and XMarks 4.1.3.  If you want the newest instructions, go here.)


Set up a WebDAV Server

If you've already done this and are just upgrading Firefox and XMarks, you can skip this section.  If you're just joining us, read on.

You need a server for XMarks to sync to, and it supports both WebDAV and FTP.  They recommend WebDAV so that's what we're using.

I have a Windows Server 2003 machine I can add it to, so the rest of the instructions in this section are for IIS 6.  You can use Apache or whatever else you want but you're on your own.  This page might help though.

Add IIS and WebDAV to the server if they're not already installed.  Go to Control Panel > Add or Remove Programs > Add/Remove Windows Components > Application Server > Internet Information Services (IIS) > World Wide Web Service and check off Word Wide Web Service and WebDAV Publishing.

Now go to Administrative Tools > Internet Information Services (IIS) Manager, find your web site (Default Web Site or one you created if you already had it installed) and go into its Properties.

I personally changed the TCP port to 8082 and made a DNS alias "FirefoxBookmarks" to the server so I can move it around if need be, but that's not required.

Go to the Home Directory tab and make sure Read and Write are checked off.  You also want to go to the folder it shows under Local Path and make sure Everyone has read and write NTFS permissions on them (right click the folder in Explorer > Properties > Security.)

Go to the HTTP Headers tab and click MIME Types.  Add .json as text/css.

You should be all set on this part.  Make sure syncing works with a manually installed and configured copy of XMarks before continuing.


Pushing Out the Configuration

This also hasn't changed since my last post, so if you're just upgrading Firefox and XMarks you can skip this.  Otherwise, read on.

Hey, remember the script from this post?  Yeah, go get that.  Change the webDAVURL variable to point to the server you just set up.  You can run it manually on your own computer until you're sure it's working correctly, but when you roll this out you want it to be a login script in Active Directory.

These are the settings it creates for you in user.js:
  • extensions.xmarks.syncOnShutdown = 1
  • extensions.xmarks.syncOnShutdownAsk = false
    Remember how I like things to Just Work™?  Well part of that is not risking the server's copy going out of date so they're wondering where their new bookmarks are, so I force the shutdown sync.  It only takes a second or two, and this way they don't have an unnecessary popup asking them about it either.
  • extensions.xmarks.useOwnServer = true
  • extensions.xmarks.url-bookmarks = "[webDAVURL]/[username]-bookmarks.json"
    This is where their bookmarks are going to be saved.
  • extensions.xmarks.url-passwords = "[webDAVURL]/[username]-passwords.json"
    This is where their passwords will be saved if they set it up.  I didn't bother trying to make it happen automatically.
  • extensions.xmarks.username = "[username]"
    Don't know if it's strictly necessary, but we want XMarks to think it's fully configured so it doesn't open the setup window.
We still have the little problem of the password.  It isn't stored in user.js so we can't push it out that way.  It isn't required by WebDAV so we don't even need it, but XMarks thinks it does and will pop up the setup window without it.  Grr.

So it's time to hack XMarks.


Editing XMarks

Go get the XMarks XPI and unpack it as described in this article.  We have a few edits to make before packing it back up into a MSI.  These edits are all based on XMarks 4.0.5 so let me know if they stop working on newer versions and I need to update these instructions.

Open modules\settings.jsm.  The JavaScript is minified so all our instructions are going to rely on search and replace.  Search for "get passwordNoPrompt(){".  Immediately after the brace add:

return "ignore";

This makes XMarks think it always has a password.  However, this still isn't enough to make it not pop up that "almost done" notification so we have to take that out too.  Open chrome\content\foxmarks-overlay.js, search for "NewUserPopup", and delete this whole section:

a.NewUserPopup(JSON.parse(d));

Now it's configured and quiet, but XMarks doesn't sync as soon as it starts up.  We want it to do that so that when someone signs in to a new computer, their bookmarks are there quickly.  While still in chrome\content\foxmarks-overlay.js, search for "},2E3" and right before that brace add:

;setTimeout(function(){Xmarks.fms.synchronize();},8000);

Don't forget that leading semicolon and be mindful of capitalization.  It's Xmarks here, not XMarks.

This syncs XMarks eight seconds after it starts up.  Why don't we just call XMarks.fms.synchronize() directly instead of using a timeout?  I did this previously but I've found that sometimes it fires before Firefox has fully loaded the bookmarks, leading XMarks to pop up a conflict message to the user about having xxx bookmarks on the server and x bookmarks in the browser.  I'm hoping this avoids that.


We're almost done, but XMarks annoyingly wants to open a tab of release notes every time it's updated.  We don't want to bug our users with this.  We can make it think it's already happened by setting "extensions.xmarks.lastUpdateVersion" in user.js, but unfortunately it can't be faked out with "99.99" like IE Tab Plus, it has to be an exact match.  We don't want to have to change this setting with every release of XMarks, and since we're editing it anyway it's easier to just disable the code.  Open modules\service.jsm, search for "firefox/upgrade", and delete everything from "Xmarks.OpenInNewTab" before it to "FoxmarksBuildPostData(b));" after it.

That's all our changes.  You can now package and push out your edited copy of XMarks as an MSI using the rest of the instructions here.  When making a new package in Active Directory, make sure you select the Advanced deployment method and set it to upgrade your previous XMarks packages on the Upgrade tab.  That will cause the old version to be uninstalled before installing this one.

Hey, couldn't I have just done all this for you and let you download the pre-hacked MSI?  No.  XMarks isn't open source, so I can't redistribute it.  I can just give you instructions on how to do it yourself.



Previous versions of this post: