I've moved my blog to http://blog.falchionconsulting.com!. Please update your links. This blog is no longer in use--you can find all posts and comments at my new blog; I will no longer be posting to this site and comments have been disabled.

As Spence points out, the preferred way to fix this is to add the host names to the BackConnectionHostNames registry key and to not set the DisableLoopbackCheck registry key. You can of course do this using Group Policy but for those not managing their servers using GPO I decided to implement a custom STSADM command that would make setting the BackConnectionHostNames registry key really simple. I called this new command, oddly enough, gl-setbackconnectionhostnames.

The command has two ways to run it, you can run it without any parameters which will cause it to update only the server in which the command is executed on, or you can pass in an -updatefarm parameter along with a username and password which will cause it to update every server in the farm. There's no need to pass in the host header names as the code will dynamically determine them by inspecting each web application and their alternate access mappings (alternate URLs) and perform some logic to determine whether the host header is pointing to a local IP address or to a specific SharePoint server (I do this to exclude Central Admin which is usually accessed using a server name and non-standard port).

I accomplish the farm update by using a custom Timer Job which executes on each server. Unfortunately the timer service account does not have access to write to the registry (unless you've given it rights, which you shouldn't) so it was necessary to pass in a username and password and then use impersonation to update the registry. The custom timer job code is shown below, notice that all the core work is being done via the SetBackConnectionHostNames class which is shown below the timer job code:

39:/// Initializes a new instance of the <see cref="SetBackConnectionHostNamesTimerJob"/> class.

40:/// </summary>

41:public SetBackConnectionHostNamesTimerJob(SPService service)

42: : base(JOB_NAME + jobId, service, null, SPJobLockType.None)

43: {

44: Title = "Set BackConnectionHostNames Registry Key";

45: }

46:

47:/// <summary>

48:/// Executes the job definition.

49:/// </summary>

50:/// <param name="targetInstanceId">For target types of <see cref="T:Microsoft.SharePoint.Administration.SPContentDatabase"></see> this is the database ID of the content database being processed by the running job. This value is Guid.Empty for all other target types.</param>

51:publicoverridevoid Execute(Guid targetInstanceId)

52: {

53:string user = Properties[KEY_USER] asstring;

54:string password = Properties[KEY_PWD] asstring;

55:

56:if (string.IsNullOrEmpty(user) || password == null)

57:thrownew ArgumentNullException("Username and password is required.");

58:

59:if (user.IndexOf('\\') < 0)

60: throw new ArgumentException("Username must be in the form \"DOMAIN\\USER\"");

There's two core methods, GetUrls and SetBackConnectionRegKey. The SetBackConnectionRegKey method started out from a bit of sample code that my friend Ben Robb sent me - there's no much of his original code but it saved me some time in trying to remember how to manipulate the registry using C#. Essentially all this method does is get the current list of host names, add any missing items to the passed in list, and then reset the list (thus avoiding duplicate entries). The GetUrls method is the more interesting piece - I'm looping through all the Farm's Web Applications and their corresponding Alternate URLs and then building a list of URLs that meet some basic inclusion criteria:

Don't add duplicates - you can get duplicates when both HTTP and HTTPS are used so we make sure that we exclude them

Don't add loopback URLs - this shouldn't come up but if the URL is localhost or 127.0.0.1 it will be flagged as a loopback URL so we exclude them

Don't add URLs that match the server name - if the host name matches the server name then exclude it (this is essentially just a short circuit for the next check which is a bit more thorough)

Exclude host names that map to the local IP address - this is the most crucial bit (the previous steps were just short circuits for this step to avoid the additional querying necessary); I use the System.Net.Dns class's static GetHostAddresses method to check the local addresses against those associated with the provided host name

Exclude host names that map to SharePoint servers - this step is necessary to address host names such as those belonging to Central Administration

The help for the command is shown below:

C:\>stsadm -help gl-setbackconnectionhostnames
stsadm -o gl-setbackconnectionhostnames
Sets the BackConnectionHostNames registry key with the URLs associated with each web application.
Parameters:
[-updatefarm (update all servers in the farm)]
[-username <DOMAIN\user (must have rights to update the registry on each server)>]
[-password <password>]

The following table summarizes the command and its various parameters:

Command Name

Availability

Build Date

gl-setbackconnectionhostnames

WSS v3, MOSS 2007

Released: 9/20/2009

Parameter Name

Short Form

Required

Description

Example Usage

updatefarm

uf

No

If provided then update the BackConnectionHostNames registry key on all servers in the farm.

-updatefarm

-uf

username

user

Yes if updatefarm is provided

The username with sufficient rights to update the registry. If no domain part is specified then the current users domain is used.

-username domain\spadmin

-user spadmin

password

pwd

No

If the users password is blank then this parameter is not required (please change your password if this is the case!); otherwise, this parameter is required if the updatefarm parameter is provided.

-password pa$$w0rd

-pwd pa$$w0rd

The following is an example of how to update the BackConnectionHostNames registry key on the current server only:

stsadm -o gl-setbackconnectionhostnames

The following is an example of how to update the BackConnectionHostNames registry key on all servers in the farm:

My Custom Commands & Cmdlets

Use of any tools included in the various downloads found at this site is at your own risk. Gary Lapointe cannot be held liable for any damage done to your environment through the use of any code or downloadable tools found on this site.

You may not repackage or sell any of the downloadable tools or associated source code. Downloading of the various tools implies that you acknowledge these restrictions.