Automatically insert Google Analytics tracking code as an outbound IIS rule


Google Analytics is a wonderful tool for tracking the behavior of visitors to a web site, but one of the things that has always been challenging for site administrators is finding a way to embed the javascript necessary to track visits via Google Analytics in to every page on a web server.  Google recommends strategies like providing server-side includes with the code embedded – but that will only work if every site on a server is using the same programming language or else is able to make use of the same set of server-side include files.  Often, that’s not the case.

If you’re running IIS 7 or later, you can now easily take care of Google Analytics code inclusion by creating an outbound rewrite rule via the web server. This outbound rule can make sure that the Google Analytics code gets injected on the response from your server to any requests.  This is helpful in a couple of ways.  When new sites or content is created, there’s no need to worry about modifying the sites or code itself to include Google Analytics. Additionally, because the script injection is handled as an outbound rule, it isn’t going to matter if the site being visited is .NET, PHP, or simply HTML – the web server include the tracking code regardless.

Setting Up the Rule

Step_One-3Setting up an outbound Google Analytics rule is pretty easy – but there are a couple of things to watch out for that we’ll talk about in just a moment.  First, let’s quickly step through setting up the rule.

As a first step, open up IIS Manager, and in the connections window, highlight the site that you wish to create a rule for.  Once highlighted, the features for that site should appear in the right hand side of your IIS Manager window.  In the features section, double-click on the feature labeled “URL Rewrite”.

In the “Actions” pane, click “Add Rule”, and a modal window will launch allowing you to define the type of rule that you want to create.  In this instance, we want to create an outbound rule using the blank outbound rule template found in the modal window.MUWWW03


  1. Give the outbound rule a recognizable name
  2. In the “Precondition” drop down menu, choose “Create a new precondition”
  3. Define the precondition using regular expressions, and add the variable {RESPONSE_CONTENT_TYPE} as the input, selecting “Matches the Pattern”, and then adding the value “^text/html” as the pattern to match.
  4. After saving your precondition, verify that the name you gave it is listed in the drop down list of the “Precondition” section of the rule that you’re creating.  If not, select it before continuing.
  5. In the “Match” section of rule definition, choose “Response” as the matching scope.  Leave “Match the content within” blank, and in the “Content” drop down, choose “Matches the Pattern” using “Exact Match”.
  6. In the “Pattern” section, enter “</head”>, and choose the “Ignore case” check box.
  7. Leave the “Conditions” section blank, and move on to the “Rewrite” section.
  8. Select “Rewrite” as the action type, and in the value, past the Google Analytics tracking code.   Make sure that “Stop processing of subsequent rules” is left unchecked – and save your rule.

Prepping the Tracking Code

There are just a couple of things that you’ll want to do to prepare the Google Analytics tracking code so that you can use it as a URL Rewrite rule within IIS.

First, paste the entire block of tracking code in to a text editor (I recommend BBEdit for Mac users or Sublime Text for Mac or Windows users) and remove any carriage returns/line breaks, leaving yourself with the entire block of tracking code from <script> to </script> on a single line.

Next, at the end of this single line, append </head> so that when the rule removes the initial </head> tag and injects the tracking code instead, the </head> code is replaced after injection.

Finally, as a last step, IIS has trouble interpreting left curly braces as a part of URL Rewrite rule syntax.  The Google Analytics tracking code uses the left curly brace by default in almost all of its iterations – so you’ll need to manually inspect the tracking code in your text editor, and replace any instance of “{” with “{UrlDecode:%7B}”.

Testing the Rule

Once you’ve finished with rule creation, click “Apply” and then check to make sure that the code is being correctly included by requesting a page on your site in a web browser.  When the page is returned, view the source of the page and make sure that the tracking code is being included in the appropriate location.

Watch Out For

  • If you find after creating the rule that you’re encountering a javascript error message along the lines of “Uncaught SyntaxError: Unexpected token….” then you’ve likely missed a left curly brace in the tracking code in your rule.  Go back and make sure that any reference to left curly braces are URLDecoded as noted in “Prepping the Tracking Code”.
  • If you run pages that make use of Adobe’s ColdFusion server, note that ColdFusion compresses outbound content, and IIS outbound rules will not work if the response is compressed since the response won’t be readable by the rule definitions. This will cause a 500 Server error on ColdFusion pages.  The best solutions I’ve been able to come up with for these sites is to disable the outbound rule on ColdFusion based sites and instead include the tracking code manually for those sites in an include file. If someone knows of a better way to solve the issue with ColdFusion pages, please let me know in the comments.



Happy 11th Birthday to my favorite girl in the world

Syd with balloon

None of these things existed until after Sydney was born:

  • The Department of Homeland Security
  • The XBox 360
  • The Nintendo Wii
  • Commercial 3G or 4G cellular networks
  • The iPhone
  • The final three Harry Potter books
  • The Tea Party

These things were still true:

  • Saddam Hussein and Bin Laden were both at large
  • Michael Jackson was still very much alive
  • Arnold had never been a governor
  • Google didn’t own Youtube
  • Pope John Paul II was still the head of the Catholic church
  • Pluto was still a planet
  • Gasoline was, on average, $1.61 a gallon
  • Nobody knew who Justin Bieber was

As hard as it is for me to accept, my baby girl turns 11 years old today.  When people say time flies, they aren’t kidding.  I’ve watched a lot change as I’ve watched my little girl grow up – in my own life, the life of friends and family, and  in the world in general.

As much as we’d like to try, we can’t promise our children a life free from difficulty, heartbreak, pain, or trauma. The best we can do is try to ground them in love, and give them the skills they need to build a great life of their own.  I hope I’m doing that for my little girl.

I’ve been very privileged to get to be the  father or not one, but two great kids. I’ve never been more proud of anything in my life than the two of them. Happy birthday darling – Love Daddy.








Tales from Higher Ed: CMS Choices Edition



The chart you see above represents an interest of “hype” chart of four popular content-management system choices over the last several years.

In blue, you see WordPress, red is Joomla, yellow is Drupal, and green is the less prominent “Concrete5″.  Expression Engine was charted, but it didn’t even register so I removed it.

When I joined Marshall University in February 2008, one of the first tasks I took on was selecting and then starting a phased implementation of a content management system for their web content.

The little circles that you see around July 2008 on the chart is when I proposed WordPress as our selection and we began implementation in earnest.

The “X” that you see on the chart is when, hilariously, a very prominent MU Alumnus who runs a web design company that I won’t name visited our campus and made the case that WordPress was a silly choice, and we should have standardized on Drupal.  Mmmmmkay.

Why does it matter where the product you’ve chosen is in this hype cycle?  Primarily because the more people you have using a product, and putting their minds to improving, supporting, and enhancing it, the better position you’re in to deliver the best product possible to your customers.

As we move through 2013 and in to 2014, it’s time to take a fresh look at where the market is at, where it’s headed, and planning for any changes we need to make in the products we’ve chosen and the way that we’ve deployed them so that in 2015 or 2016 we can be similarly position on a hype chart a few years later.

Part of being a good leader is having confidence in your decisions and the information you use to make them. Listen to feedback, take in to consideration criticisms, but don’t just listen to someone because of who they are or who they know. Use data to confirm the decisions you make, and constantly reevaluate and adjust based on the results of your own analysis.

5 Tips for Protecting Yourself and Your Kids from “Free” Children’s Games on the iPhone or iPad

iOS devices are great for kids. They’re easy to use, and there are a bevy of solid educational apps that children can understand and use without a tremendous amount of effort. They’re also a great way to introduce children to computing, and give them something (at times) constructive to do in those life moments where they need a distraction.

That being said, make sure you closely watch the apps that your children are using. In the past, a number of apps that have shown up as free downloads in the App Store have ended up surprising parents with large credit card charges later via the use of in-app purchases.

This problem has impacted parents even in some of the more popular free apps – perhaps most highly visible in the “Smurf’s Village” game that generated a number of news stories a couple of years ago.  For background on this story, click any of the links below.

Smurf’s Village certainly isn’t the only app in the App Store to employ this deceitful money-making strategy. As it’s been successful, more and more app makers have attempted to profit through the in-app purchases of unknowing users.

Never, though, have I seen this strategy taken to as egregious extremes as in the app “Super Monster Bros by Adventure Time Pocket Free Games” (yes, that’s the actual name of the app).

To see for yourself how far this game takes things, take a few minutes to watch the following game review.  The reviewers walk through the game, and you’ll see for yourself how each it would be for a child to end up spending a lot of money without being aware of it.

Tips for Protecting Yourself and Your Child

Fortunately, there are some simple steps you can take to protect yourself and your child from mistaken purchases.

1. Regularly monitor the apps that your child is using. If they share an iTunes account with you, you can see a list of purchased apps at any time by launch the App Store on your iOS device, and clicking on “Updates>Purchased”.  You’ll see a list of the apps purchased and installed across devices in this list.

2. Even if an app is listed as free, check in to it to determine whether it supports in-app purchasing. A good way to get a feel for the integrity of the app is to look over the app reviews to see what others are saying about the app. In addition to this, it’s also a good idea to see if the more popular apps show up in the “Top Grossing” list of apps in the app-store.  If an app is listed as free, yet still shows up in the “Top Grossing” app list, then you can safely assume it’s making a lot of profit from the in-app purchases being sold in the game. You can find the list of top-grossing apps by launching the app store on your iOS device, clicking the “Top Charts” link at the bottom, and scrolling all the way down to find the list of top-grossing apps.

3. If your child is using their own iTunes account, rather than tying it to your credit card, you can use an iTunes gift card to setup and fund the AppleID associated with the device.  Purchase a low-value iTunes card to get the account setup. Once the gift card value has been used, any attempts to make any kind of purchase on the account will generate a request for refunding. This greatly limits your exposure to abuse from unscrupulous developers.

4. Enable restrictions to prevent in-app purchasing. iOS allows you to restrict what activities are allowed on a per-device basis via the “Settings” app.  Launch the “Settings” app on the iOS device that you want to control, and click “General>Restrictions”. By default, all restrictions are turned off – so the first thing you need to do is click the “Enable Restrictions” button at the top of this page. Once you’ve clicked that, you’ll be asked to provide and confirm a four digit passcode that will be used in the future to access the device restrictions.  Once your passcode has been entered, scroll down to the “Allowed Content” section of the restrictions panel and toggle “In-App Purchases” to off.  Once you’ve done this, attempts to make purchases within any app – even accidentally – will simply present a notice that in-app purchases have been disable on this device.  If you find you need to make legitimate in-app purchases in the future, turning this off is as simple as visiting the restrictions app again and changing the toggle.

5. If you find that you’ve been accidentally bilked out of money through mistaken in-app purchases, make sure to dispute the charges with Apple. While Apple’s policy states that all purchases are final, there have been many reports of users who have had success having charges reversed when it’s clear that an app is abusing the in-app purchase system. It’s worth trying to get charges reversed if you’ve had this happen to you. To start the process, launch iTunes on your computer, and click the iTunes Store icon or button (depending on your version of iTunes). Once in the iTunes store, click on your account name, and choose “Account” from the list that appears. Under “Purchase History”, click “See All”, and find the app in this list that generated the charges. Click the small gray arrow next to the app name, and choose “Report a Problem” from the menu that appears. You’ll be taken to the “Report a Problem” page where you can select “I inadvertently purchased this app”.  Enter comments about the abusive in-app purchase charges, and ask that the charges be reversed before you hit “Submit”.

Defending against WordPress brute-force attacks using built in features of IIS

Throughout the past week, a very large network of compromised computers has been pounding away at sites using the WordPress content management platform, attempting to access those sites by continually attempting logins using default WordPress usernames, along with a combination of passwords.

For these attacks to work, the attacking machines have to continually try various combinations of passwords, throwing request after request at your system, until they find a combination that works.

One of the best ways to defend against such an attack is to make sure that you’re not using default usernames.  Even if you’re doing that, though, it doesn’t prevent the attackers from throwing posts at your WordPress points of entry.  This forces WordPress to have to process these attempted logins before determining that the username is invalid.

While there’s no major security vulnerability, when attackers are throwing post after post at your installation, it can hamper performance dramatically.

There’s plenty of advice online for people who’ve installed WordPress using an Apache web server, but not as much for people using IIS. Fortunately, IIS has some features that can help mitigate the problem.

Dynamic IP Restrictions

A great first line of defense is available by installing the Dynamic IP Restrictions extension (link).

Once installed, you’ll can configure your site to deny requests from any IP address that is sending too many requests to your server too quickly, based on the criteria you define in the configuration.























Inbound Rewrite Rule

Another great idea is placing a rewrite rule on your wp-login.php file that checks for certain conditions prior to processing a user login.  When a bot attempts to login to your site using an automated routine, you will usually see a post of attempted credentials directly to your wp-login.php file.  This allows for rapid automation of multiple login attempts.

This looks different than someone actually visiting your WordPress admin, and clicking the “Login” button after supplying credentials.  Specifically, when a post is coming directly from a bot, the header sent along with the post will be usually be missing the HTTP_REFERER header.  Knowing this can help you construct a rewrite rule that will prevent these attempted logins from being processed.

In Features view, click on the “URL Rewrite” icon, and click “Add Rule” in the Actions pane on the right.

Give your rule a name, and in the Requested URL drop down, choose “Matches the Pattern”. Choose “Wildcard” under “Using”.

In the pattern box, enter *wp-login.php*.  This pattern allows you to also catch any redirects caused by someone visiting a site at the /wp-admin/ URL.

Under “Conditions” choose “Match All”, and add the following two conditions:

1. {HTTP_REFERER} Does Not Match the Pattern *wp-login.php*

2. {REQUEST_METHOD} Matches the Pattern POST

Under “Action”, choose “Abort Request”

This rule should catch any automated attempt to post directly to wp-login.php, and stop the request before WordPress actually attempts to process it, allowing for improved performance.