I thought it was about time to bust one quite common myth in the SharePoint world (and there are lot of them!). This one in particular is interesting because it can cause you some interesting troubles, or at least some embarrassment. This is about that you can determine the current SharePoint  version by checking the HTTP Response Header called MicrosoftSharePointTeamServices. So let’s bust that myth, or at least try!
On a standard installed SharePoint Farm when you request a page you will get a set of response headers back. One of these response headers are named MicrosoftSharePointTeamServices and it has a version number as value, like this:
As you can see in the image the version number is 22.214.171.12414, which corresponds to SharePoint 2010 (14) and December 2011 Cumulative Update (6114).
This header is not added by SharePoint (in the pipeline) but rather by IIS, even though it is SharePoint who adds it to IIS.
If you fire up the IIS manager and go to a SharePoint web site and check the HTTP Response Headers Feature, you can see that it is configured there.
If you check the Central Administration Web Site you’ll it also have the same exact version value.
You can even change the headers in the IIS Manager (what good that now would do). So we basically already busted the myth! But let’s assume that you don’t fiddle with this and continue our research…
Applying a cumulative update
Let’s take this 6114 farm, which was a slipstreamed 6114 install, and apply the April 2012 CU (6120) and see what happens. After applying the April CU we’re seeing this in the returned header on our Central Administration that the response headers shows the correct value – 126.96.36.19920.
Now, take a look at the header on the content web application that we looked at before the B2B upgrade:
6115!!! What!? After checking both Todd and Todd’s version lists we have no idea what version this is?!? It is something in-between December 2011 and February 2012! Ok, let’s apply June 2012 CU, which is build number 6123, on top of this. After running the Configuration Wizard again this is response header we’re receiving.
6122! Close but no cigar! Central Admin on the now patched farm still shows the correct build (6123).
Adding a new Web Application
Now let’s do another experiment – add a new Web Application to this farm. After that we’ll see that it actually contains the correct version header (6123).
Adding a new server to the farm
One final experiment, let’s add a new server to this farm, that was upgraded from December 2011, to April 2012 and then to June 2012 CU, with a slipstreamed June 2012 machine. This is how it looks if we browse to the original web application (that we updated twice).
The newly created one, shows the “correct” build. Also a check in the IIS verifies that both web sites have the “correct” build number in the response headers feature.
This is interesting, this means that in a load balanced scenario you could actually get different build values from the response header!
Let’s do this experiment once again but slightly different. This time instead of running the Configuration Wizard after applying the patch, let’s do it the hard core way by using psconfig.exe:
psconfig.exe -cmd upgrade -inplace b2b -wait
The key here is that I use the –wait flag, which makes sure that the upgrade process is executed as the user running the command, instead of in the owstimer.exe process (which is running as the farm account).
Low and behold, now the response header shows the correct build version (6123) in Central Admin and on the content web application!
Why these strange build numbers?
To make a long story short it all comes down to how the farm is updated, specifically which account you’re doing the upgrade with. We can also say that if you’re running the Configuration Wizard and get the “correct” build number in the response headers, you’re farm is misconfigured :-). When I ran the psconfig.exe command with the –wait switch I used an account that was a member of the local Administrators group, whereas my farm account (running the owstimer.exe process) is not.
Deep down between the zeroes and ones in the SharePoint code there is actually a code snippet that checks if the account running the upgrade is a member of the local Administrators group. If the account is member it will nice and quietly update the IIS metabase with the (file) build number, taken from the current assembly which is Microsoft.SharePoint.dll. But if the user is not a local Administrator (and cannot edit the metabase), the operation is passed on to the WSSAdmin component (running as Local System) which uses another assembly. This assembly is called Microsoft.SharePoint.AdministrationOperation.dll, and the metabase is updated with the (file) build number for that assembly. This table below shows you the version info for the two CU’s we’ve been looking at.
April 2011 Cumulative update
June 2012 Cumulative update
Fortunately in these cases the AdministrationOperation dll has had changes between released CU’s, but what will happen the one day when there is no need to patch that assembly. Well, in that case the build number will stay as in the previous version/build/CU.
So there you have it – you cannot trust this MicrosoftSharePointTeamServices response header as a single source of trust when you need to remotely find out your SharePoint build and version. Even if you keep track of all the specific builds of the administration assembly, since it might not be updated, and you cannot be sure that everyone runs psconfig with the –wait switch.
The myth is busted!
SharePoint Designer shows the correct version!?
Let’s take a look at how you can retrieve the correct version number remotely. It hurts me to tell you – but the best source for this is to use SharePoint Designer! Yes, SharePoint Designer shows you the current build in site information panel.
Note: SharePoint Designer uses a call to /_vti_bin/shtml.dll/_vti_rpc to find out the version number
“I read somewhere that the Client Object Model has the correct version number!”
When we take a look at the response from this request we’ll see this:
6108! That is somewhere in-between the June 2011 CU and the August 2011 CU, a year old stuff! It is basically the same reason as previously, this build number is fetched from the Microsoft.SharePoint.Client.ServerRuntime.dll assembly, and that one has not been/needed to be updated since last year (someone give that PM a nice cake!).
How about removing the header?
Someone of you might think that it is a good idea to remove this header, since it can at least tell you (or your enemies) something about your farm. Ok, for a public facing WCM site (or public facing blog sites :-) it might make sense, but if you do it you must know that it will cause troubles when crawling, people will not be able to work with documents etc etc. So just don’t do it without a proper cause and testing.
Note: Disabling Client Integration on the web application will remove the response header.
That was fun, right? We did bust a myth about how you can find out the current SharePoint version just by looking at the HTTP response headers. The MicrosoftSharePointTeamServices response header really doesn’t say anything (except some kind of minimum build level) since you don’t know how they built/slipstreamed the install or upgraded the farm.