This website Saotn.org has been hosted on Windows Server 2012 with IIS 8.0 and WordPress for a few months now, and everything runs very smoothly. I would never have hit this bug, because I don't need to change my permalink structure. One of my colleagues, on the other hand, just moved his website to an IIS 8.0 web server, and he noticed he couldn't save his permalink structure in the IIS web.config file. That can be pretty annoying ๐ We found the cause, reported it and it got fixed in WordPress core.
WordPress 3.4 and 3.5 only recognized IIS 7.x as an IIS version that supports web.config rewrite rules, so on IIS 8.0 saving permalinks to web.config failed. We reported it in WordPress Trac ticket #23533, and Changeset 24594 fixed it for IIS 8 and above.
I originally wrote this post in February 2013. The bug was fixed in WordPress core in 2013, so you don't need the quick fix below on any current WordPress version. I keep this post online because it is a nice bit of WordPress-on-IIS history.
Why WordPress could not save permalinks on IIS 8.0
With a few other colleagues we went to investigate why WordPress wouldn't save permalinks on Windows Server. Because of recent issues we encountered with Helicon Ape and the .NET Framework, that was our first point of investigation. Maybe a recent update of Helicon Ape, or of the .NET Framework (Patch Tuesday security updates), broke some permission structure? Well, we were wrong...
During the investigation one colleague looked at the file wp-includes/vars.php, and he noticed a hard check on IIS version 7.x. The result was that WordPress 3.5 on IIS 8.0 was unable to write a web.config file, due to insufficient server version checking. Did the WordPress developers never think of IIS 8.0? Were we the first hosting company hosting WordPress websites on IIS 8.0? ๐
Want to see? In WordPress 3.5, wp-includes/vars.php contained these lines (lines 95 - 99):
/**
* Whether the server software is IIS 7.X
* @global bool $is_iis7
*/
$is_iis7 = $is_IIS && (strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS/7.') !== false);
IIS 8.0 identifies itself as Microsoft-IIS/8.0, so $is_iis7 was false, and WordPress didn't even try to write the rewrite rules to web.config.
Quick fix for WordPress 3.5 and IIS 8.0
The quickest fix was to change this line, so it also accepts IIS 8.x:
$is_iis7 = $is_IIS && (strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS/7.') !== false
|| strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS/8.') !== false);
This extends the check to IIS 7.x or 8.x. Mind the !== false on both comparisons: strpos() returns 0 when the string starts with Microsoft-IIS/, and 0 evaluates to false in PHP. I could imagine a more elegant fix would exist, though.
WordPress 3.5 on IIS 8.0 bug reported
We filed this as a bug in ticket #23533 on core.trac.wordpress.org: "WordPress doesn't recognize IIS 8.0 (Windows Server 2012) properly". According to the WordPress developers, the bug was introduced in WordPress 3.4.
The WordPress patch
Update, July 2013: the approved patch for the reported bug is WordPress Changeset 24594, "Support IIS 8 and above". Instead of matching a version string, WordPress now reads the IIS major version number and checks whether it is 7 or higher. This is the line in wp-includes/vars.php today:
$is_iis7 = $is_IIS && (int) substr( $_SERVER['SERVER_SOFTWARE'], strpos( $_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS/' ) + 14 ) >= 7;
That is the more elegant fix I was hoping for, and it covers IIS 10 on current Windows Server versions as well.
Running WordPress on IIS? Have a look at my WordPress web.config, and learn how to convert .htaccess to web.config for the IIS URL Rewrite Module.