Home
About
Contact
Monday, February 15, 2010

In part 1 I explained why I needed a load balancer that was capable of doing smart balancing decisions using more than just IPs and why I decided to use IIS7 and Application Request Routing (ARR). In this part I will give a detailed explanation of how to setup ARR on Windows Server 2008 R2 Web Server Core.

Server Core provide the following benefits over traditional installations according to Microsoft:

  • Reduced maintenance
  • Reduced attack surface
  • Reduced management
  • Less disk space required

I concluded that the above points is quite important for a load balancer, as you don’t want it to spend its resources on anything else than load balancing.

In this guide I will walk you through the steps needed to install Windows Server 2008 Web Server Core. Secondly I will show you how to create the necessary scripts to automate about 99% of the installation and configuration of ARR.

Before we dig deep, here’s a short description of the setup I used for my ARR environment:

Two Web Servers with:

  • 3 websites running both SSL and normal HTTP
  • Each website needed its own IP
  • Each website needed its own SSL certificate

ARR Server:

  • In order to avoid the “clients NAT’ed behind one IP” problem, I needed to configure ARR Server Affinity to UseCookie.
  • As for the Load Balancing Algorithm I used Weighted Round Robin (you should look into the other alternatives that suite your needs)
  • The ARR server is responsible for distributing traffic to two web servers mentioned above

All of the above can of course be changed in the scripts that I’ll be showing later to suite your configuration needs. Below is an illustration of the infrastructure:

image

Installing Windows Server 2008 R2 Web Server Core:

  1. Install Windows Server 2008 R2 Web - Server Core
  2. Set password for admin (when prompted)
  3. Rename server:
    NETDOM renamecomputer %computername% /newname:[nameOfServer]
  4. Restart:
    shutdown /r /t 0
  5. Set static IP:
    netsh interface ipv4 set address "Local Area Connection" static [IP] [Subnet] [Gateway]
  6. Set Primary DNS server:
    netsh interface ipv4 add dnsserver "Local Area Connection" [IP]
  7. Set Secondary DNS server:
    netsh interface ipv4 add dnsserver "Local Area Connection" [IP] index=2
  8. If you want the server to join a domain:
    netdom join %computername% /domain:[domainname] /userd:[username] /passwordd:*
  9. Restart:
    shutdown /r /t 0
  10. If you want to enable Remote Desktop:

    For Vista/Win7/2008 clients:
    cscript %windir%\system32\SCRegEdit.wsf /ar 0

    For earlier clients:
    cscript %windir%\system32\SCRegEdit.wsf /cs 0

    For both new and earlier clients run both of the above
  11. If you want to allow remote MMC management (e.g. to simplify managing users etc):
    netsh advfirewall firewall set rule group="Remote Administration" new enable=yes
  12. Activate Windows:
    start /w slmgr.vbs –ipk [key]
    start /w slmgr.vbs –ato

Now the server is ready for ARR installation and configuration, but since the OS is a server core, creating some scripts to automate this procedure is very helpful. Next I will show you the scripts I created and used, which hopefully will make this task easier for you than for me :-) I’ve made all the files and scripts available in this zip file.

Creating script for installing SSL certificates (do this on some client computer, not the ARR Server):

Note: You can skip this section (except step 1 and 2) if you’re not using SSL.

  1. Create a folder called ARRInstall
  2. In the ARRInstall folder, create a new folder called Utils
  3. Download capicom_dc_sdk.msi and place MSI in the Utils folder
  4. Download winhttpcertcfg.msi and install with default options on a client computer
  5. Browse to C:\Program Files (x86)\Windows Resource Kits\Tools\ and copy winhttpcertcfg.exe into your Utils folder
  6. Create a folder called Certificates in your ARRInstall folder
  7. The above folder must contain all your certificates (both with and without private keys). For my setup this looks like this:

    ARRInstall 
      |-- Certificates 
            |-- site1.torresdal.net.cer 
            |-- site1.torresdal.net.pfx 
            |-- site2.torresdal.net.cer 
            |-- site2.torresdal.net.pfx 
            |-- site3.torresdal.net.cer 
            |-- site3.torresdal.net.pfx
  8. Copy the script below, read comments in script and modify accordingly. Then save the script as _SetupCertificates.cmd in the ARRInstall folder:
    @echo off
    
    echo Installing CAPICOM...
    
    echo.
    
    msiexec /qn /i "%~dp0Utils\capicom_dc_sdk.msi"
    
    echo Removing existing certificate from store...
    
    REM Example:
    
    REM certutil -delstore Root "blog.torresdal.net"
    
    certutil -delstore Root "[certificate name]"
    
    echo Removing SSL certificate from IIS...
    
    netsh http delete sslcert ipport=0.0.0.0:443
    
    echo Installing certificates...
    
    echo.
    
    REM Example:
    
    REM certutil -f -addstore Root "%~dp0Certificates\blog.torresdal.net.cer"
    
    certutil -f -addstore Root "%~dp0Certificates\[certificate name].cer"
    
    IF EXIST "%PROGRAMFILES%\Microsoft CAPICOM 2.1.0.2 SDK" (
    
        SET capicompath="%PROGRAMFILES%\Microsoft CAPICOM 2.1.0.2 SDK\Samples\vbs\cstore.vbs"
    
        SET cscript=%windir%\system32\cscript.exe
    
    )
    
    IF EXIST "%PROGRAMFILES(x86)%\Microsoft CAPICOM 2.1.0.2 SDK" (
    
        SET capicompath="%PROGRAMFILES(x86)%\Microsoft CAPICOM 2.1.0.2 SDK\Samples\vbs\cstore.vbs"
    
        SET cscript=%windir%\syswow64\cscript.exe
    
        ECHO Setting up CAPICOM for 64 bits environment...
    
        copy /y "%PROGRAMFILES(x86)%\Microsoft CAPICOM 2.1.0.2 SDK\Lib\X86\capicom.dll" %windir%\syswow64
    
        %windir%\syswow64\regsvr32.exe /s %windir%\syswow64\capicom.dll
    
    )
    
    REM Example:
    
    REM %cscript% /nologo %capicompath% delete -l LM -subject "blog.torresdal.net" -noprompt
    
    %cscript% /nologo %capicompath% delete -l LM -subject "[certificate name]" -noprompt
    
    REM Example:
    
    REM %cscript% /nologo %capicompath% import -l LM "%~dp0Certificates\blog.torresdal.net.pfx" "somePassword"
    
    %cscript% /nologo %capicompath% import -l LM "%~dp0Certificates\[certificate name].pfx" "[password]"
    
    REM Example:
    
    REM "%~dp0Utils\winhttpcertcfg.exe" -g -c LOCAL_MACHINE\My -s blog.torresdal.net -a "IIS_IUSRS"
    
    "%~dp0Utils\winhttpcertcfg.exe" -g -c LOCAL_MACHINE\My -s [certificate name] -a "IIS_IUSRS"
    
    echo.
    
    echo ============================
    
    echo Certificates Setup finished!
    
    echo ============================
    
    REM pause
    
    :end
  9. Your folder structure should now look like this:
    ARRInstall 
      |-- Certificates 
            |-- site1.torresdal.net.cer 
            |-- site1.torresdal.net.pfx 
            |-- site2.torresdal.net.cer 
            |-- site2.torresdal.net.pfx 
            |-- site3.torresdal.net.cer 
            |-- site3.torresdal.net.pfx
      |-- Utils
            |-- capicom_dc_sdk.msi
            |-- winhttpcertcfg.exe
      |-- _SetupCertificates.cmd

Create script for installing and configuring ARR:

  1. Download the x64 installer for ARR from the ARR website: http://www.iis.net/expand/ApplicationRequestRouting
  2. Copy the downloaded file (ARRv2_setup_x64.EXE) into the Utils folder
  3. Download IIS7Util.exe which I’ve made available for you on my site. (The source code can be found at the foaf-ssl-dotnet project. Just browse code and search for “iis7util”, to make it clear where I got it from :-))
  4. Copy the IIS7Util.exe into the Utils folder
  5. Copy the script below, read comments in script and modify accordingly. Then save the script as InstallARR.cmd in the ARRInstall folder. You should then have this file structure:

    ARRInstall 
      |-- Certificates 
            |-- site1.torresdal.net.cer 
            |-- site1.torresdal.net.pfx 
            |-- site2.torresdal.net.cer 
            |-- site2.torresdal.net.pfx 
            |-- site3.torresdal.net.cer 
            |-- site3.torresdal.net.pfx
      |—Utils
            |-- ARRv2_setup_x64.EXE
            |-- capicom_dc_sdk.msi
            |-- IIS7Util.exe
            |-- winhttpcertcfg.exe
      |-- _SetupCertificates.cmd
      |-- InstallARR.cmd

    Note: If you’re not using SSL, comment out this line in your script:
    call %~dp0_SetupCertificates.cmd

    @echo off
    
    REM =====================
    
    REM 	CONFIGURATION
    
    REM =====================
    
    REM =============================================
    
    REM IP's for the different sites on the LB Server
    
    REM =============================================
    
    SET Site1IPNLB=10.0.0.51
    
    SET Site2IPNLB=10.0.0.52
    
    SET Site3IPNLB=10.0.0.53
    
    REM =============================
    
    REM IP's for back end web servers
    
    REM =============================
    
    SET Site1IPWeb01=10.137.13.61
    
    SET Site2IPWeb01=10.137.13.62
    
    SET Site3IPWeb01=10.137.13.63
    
    SET Site1IPWeb02=10.137.13.71
    
    SET Site2IPWeb02=10.137.13.72
    
    SET Site3IPWeb02=10.137.13.73
    
    REM ==============================
    
    REM Host names for different sites
    
    REM ==============================
    
    SET Site1HostName=site1.torresdal.net
    
    SET Site2HostName=site2.torresdal.net
    
    SET Site3HostName=site3.torresdal.net
    
    REM ==================================
    
    REM Name of Server Farms for each site
    
    REM ==================================
    
    SET ARRServerFarm1=Site1
    
    SET ARRServerFarm2=Site2
    
    SET ARRServerFarm3=Site3
    
    REM ============================
    
    REM File locations for web sites
    
    REM ============================
    
    SET Site1FileLoc=C:\%ARRServerFarm1%
    
    SET Site2FileLoc=C:\%ARRServerFarm2%
    
    SET Site3FileLoc=C:\%ARRServerFarm3%
    
    REM ==========
    
    REM AppCmd.exe
    
    REM ==========
    
    SET AppCMD=%windir%\system32\inetsrv\appcmd.exe
    
    REM =========================
    
    REM	INSTALLATION
    
    REM =========================
    
    Echo Installing IIS...
    
    start /w pkgmgr /l:log.etw /iu:IIS-WebServerRole;WAS-WindowsActivationService;WAS-ProcessModel;WAS-NetFxEnvironment;WAS-ConfigurationAPI;NetFx2-ServerCore;NetFx2-ServerCore-WOW64;IIS-ManagementService
    
    Echo Enabling remote management of IIS...
    
    reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WebManagement\Server /v EnableRemoteManagement /t REG_DWORD /d 1 /f
    
    sc config WMSVC start= auto
    
    Echo Installing Application Request Routing (ARR)...
    
    net stop was /y
    
    net stop wmsvc /y
    
    "%~dp0utils\ARRv2_setup_x64.EXE" /Q
    
    net start was
    
    net start wmsvc
    
    Echo Disable Idle Timeout on Application Pool...
    
    %AppCMD% set apppool "DefaultAppPool" -processModel.idleTimeout:"00:00:00" /commit:apphost
    
    %AppCMD% set config -section:system.applicationHost/applicationPools /[name='DefaultAppPool'].recycling.periodicRestart.time:"00:00:00" /commit:apphost
    
    Echo Installing certificates...
    
    call %~dp0_SetupCertificates.cmd
    
    Echo Adding aditional IPs for web sites...
    
    netsh interface ipv4 add address "Local Area Connection" %Site1IPNLB% 255.255.255.0
    
    netsh interface ipv4 add address "Local Area Connection" %Site2IPNLB% 255.255.255.0
    
    netsh interface ipv4 add address "Local Area Connection" %Site3IPNLB% 255.255.255.0
    
    Echo Creating folders for web sites...
    
    md %Site1FileLoc%
    
    md %Site2FileLoc%
    
    md %Site3FileLoc%
    
    Echo Creating web sites in IIS...
    
    %AppCMD% add site /name:%site1HostName% /bindings:"http/%Site1IPNLB%:80:,https/%Site1IPNLB%:443:" /physicalPath:"%Site1FileLoc%"
    
    %AppCMD% add site /name:%site2HostName% /bindings:"http/%Site2IPNLB%:80:,https/%Site2IPNLB%:443:" /physicalPath:"%Site2FileLoc%"
    
    %AppCMD% add site /name:%site3HostName% /bindings:"http/%Site3IPNLB%:80:,https/%Site3IPNLB%:443:" /physicalPath:"%Site3FileLoc%"
    
    Echo Adding farms and servers to ARR...
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm1%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm1%'].[address='%Site1IPWeb01%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm1%'].[address='%Site1IPWeb02%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm2%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm2%'].[address='%Site2IPWeb01%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm2%'].[address='%Site2IPWeb02%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm3%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm3%'].[address='%Site3IPWeb01%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm3%'].[address='%Site3IPWeb02%']" /commit:apphost
    
    REM ==============================================================================
    
    REM ALERT!: REMEMBER THAT SSL RULES FOR EACH SITE MUST BE BEFORE THE HTTP RULES!!!
    
    REM 	    E.g. 1) Rules for Site1 SSL
    
    REM              2) Rules for Site1 HTTP
    
    REM		 3) Rules for Site2 SSL
    
    REM		 4) Rules for Site2 HTTP
    
    REM		 5) etc.
    
    REM
    
    REM	    If we had switched 1 and 2, it would match on HTTP first, and would
    
    REM	    have redirected to a non SSL site, resulting in SSL offloading.
    
    REM
    
    REM	    If SSL offloading is the wanted behaviour, only the HTTP rule is 
    
    REM	    nessesary.
    
    REM ==============================================================================
    
    echo Adding rewriting rules to ARR...
    
    %AppCMD% clear config -section:system.webServer/rewrite/globalRules
    
    REM Site1 SSL
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm1%_SSL', patternSyntax='Wildcard',stopProcessing='True']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm1%_SSL',patternSyntax='Wildcard',stopProcessing='True'].match.url:"*"  /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm1%_SSL',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTPS}',pattern='on']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm1%_SSL',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTP_HOST}',pattern='*%Site1HostName%*']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm1%_SSL',patternSyntax='Wildcard',stopProcessing='True'].action.type:"Rewrite" /[name='%ARRServerFarm1%_SSL',patternSyntax='Wildcard',stopProcessing='True'].action.url:"https://%ARRServerFarm1%/{R:0}" /commit:apphost
    
    REM Site1 HTTP
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm1%', patternSyntax='Wildcard',stopProcessing='True']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm1%',patternSyntax='Wildcard',stopProcessing='True'].match.url:"*"  /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm1%',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTP_HOST}',pattern='*%Site1HostName%*']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm1%',patternSyntax='Wildcard',stopProcessing='True'].action.type:"Rewrite" /[name='%ARRServerFarm1%',patternSyntax='Wildcard',stopProcessing='True'].action.url:"http://%ARRServerFarm1%/{R:0}" /commit:apphost
    
    REM Site2 SSL
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm2%_SSL', patternSyntax='Wildcard',stopProcessing='True']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm2%_SSL',patternSyntax='Wildcard',stopProcessing='True'].match.url:"*"  /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm2%_SSL',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTPS}',pattern='on']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm2%_SSL',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTP_HOST}',pattern='*%Site2HostName%*']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm2%_SSL',patternSyntax='Wildcard',stopProcessing='True'].action.type:"Rewrite" /[name='%ARRServerFarm2%_SSL',patternSyntax='Wildcard',stopProcessing='True'].action.url:"https://%ARRServerFarm2%/{R:0}" /commit:apphost
    
    REM Site2 HTTP
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm2%', patternSyntax='Wildcard',stopProcessing='True']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm2%',patternSyntax='Wildcard',stopProcessing='True'].match.url:"*"  /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm2%',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTP_HOST}',pattern='*%Site2HostName%*']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm2%',patternSyntax='Wildcard',stopProcessing='True'].action.type:"Rewrite" /[name='%ARRServerFarm2%',patternSyntax='Wildcard',stopProcessing='True'].action.url:"http://%ARRServerFarm2%/{R:0}" /commit:apphost
    
    REM Site3 SSL
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm3%_SSL', patternSyntax='Wildcard',stopProcessing='True']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm3%_SSL',patternSyntax='Wildcard',stopProcessing='True'].match.url:"*"  /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm3%_SSL',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTPS}',pattern='on']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm3%_SSL',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTP_HOST}',pattern='*%Site3HostName%*']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm3%_SSL',patternSyntax='Wildcard',stopProcessing='True'].action.type:"Rewrite" /[name='%ARRServerFarm3%_SSL',patternSyntax='Wildcard',stopProcessing='True'].action.url:"https://%ARRServerFarm3%/{R:0}" /commit:apphost
    
    REM Site3 HTTP
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm3%', patternSyntax='Wildcard',stopProcessing='True']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm3%',patternSyntax='Wildcard',stopProcessing='True'].match.url:"*"  /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm3%',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTP_HOST}',pattern='*%Site3HostName%*']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm3%',patternSyntax='Wildcard',stopProcessing='True'].action.type:"Rewrite" /[name='%ARRServerFarm3%',patternSyntax='Wildcard',stopProcessing='True'].action.url:"http://%ARRServerFarm3%/{R:0}" /commit:apphost
    
    REM ===============
    
    REM Server Affinity
    
    REM ===============
    
    Echo Adding Server Affinity...
    
    %AppCMD% set config  -section:webFarms /[name='%ARRServerFarm1%'].applicationRequestRouting.affinity.useCookie:"True"  /commit:apphost
    
    %AppCMD% set config  -section:webFarms /[name='%ARRServerFarm2%'].applicationRequestRouting.affinity.useCookie:"True"  /commit:apphost
    
    %AppCMD% set config  -section:webFarms /[name='%ARRServerFarm3%'].applicationRequestRouting.affinity.useCookie:"True"  /commit:apphost
    
    REM ========================
    
    REM Load Balancing Algorithm
    
    REM ========================
    
    Echo Adding Load Balancing Algorithm...
    
    %AppCMD% set config  -section:webFarms /[name='%ARRServerFarm1%'].applicationRequestRouting.loadBalancing.algorithm:"WeightedRoundRobin" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /[name='%ARRServerFarm2%'].applicationRequestRouting.loadBalancing.algorithm:"WeightedRoundRobin" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /[name='%ARRServerFarm3%'].applicationRequestRouting.loadBalancing.algorithm:"WeightedRoundRobin" /commit:apphost

Installing Application Request Routing:

  1. From the ARR server connect to your client containing the script files:
    net use [some drive letter]: \\clientComputerName\[drive on client]$ /user:domain\user
    Example:
    net use r: \\myClient\c$ /user:torresdal\jon
  2. Make a directory on the server to copy the files to:
    E.g.: md c:\temp\arr
  3. Copy the ARRInstall folder from your client to C:\temp\arr on your server
  4. Run InstallARR.bat, watch for errors and wait for it to finish
  5. Install Remote IIS Manger on a PC that will administrate IIS and connect to the ARR server: http://www.iis.net/expand/IISManager
  6. In Internet Information Services Manager connected to ARR do:
    1. Select Sites->Site1
    2. Click Bindings (upper right corner)
    3. Click https –> Edit
    4. Select proper certificate
    5. Repeat for all other sites
  7. Under Sites:
    1. For each site that require SSL:
      1. Click SSL Settings
      2. Check Require SSL
  8. Start IIS on ARR server:
    iisreset /start
  9. Using Internet Information Services Manager:
    Stop “Default Web Site”
  10. You’re done!

I hope this helped in making the installation and configuration of the ARR server easier, and that my scenario is applicable to others except me :-) Let me know if I can help with questions or if you find any errors.

Next time I will talk about how to avoid the ARR server being the Single Point of Failure.

Monday, February 15, 2010 8:00:00 AM (W. Europe Standard Time, UTC+01:00)
Wednesday, February 10, 2010

image A few weeks back I had to solve a performance problem at work. For some of our applications most of our users are NAT’ed behind the same IP, making the default load balancer (NLB) in Windows direct the majority of all traffic to one server. NLB in Windows work on layer 3 (network layer) in the OSI model (that thing you learned at uni), meaning we can only take advantage of IP stuff. So usually you use what’s often called Sticky Sessions (Single Affinity) to keep track of which IP’s got redirected to which server, and keep doing that from that point on for that IP. This was the setup we had.

You can work around that problem by disabling Sticky Sessions, but it might influence performance and could give you unwanted consequences. As an example, if you use ASP.NET Web Forms you will probably run into an issue with ViewState and possibly session issues. For SSL however (which was the case for us), Sticky Session is not recommended.

Other “smarter” load balancers work on layer 7 (application layer), providing us with a much bigger toolbox to inspect traffic and make smarter choices for where to redirect traffic. So I started to look for a load balancer on layer 7. The obvious first choice was hardware LB. This is often the quickest solution, but also the most expensive. I looked at Cisco’s Application Control Engine Module (ACE) and F5 BigIP, but the price was and issue as well as the lack of people with know-how inside our organization of how to configure them.

My next option was setting up a Linux server running Apache and LB, but then I came across a Microsoft module on IIS7: Application Request Routing (ARR). I found some really good documentation and it looked quite easy to set up. Since I (and others in my organization) are used to working with IIS, this seamed to be worth investigating.

In my next post I’ll go trough all the details of setting up ARR on Windows 2008 R2 Server Core. Everything from installing and configuring the OS to automate installation of ARR by scripts.

Wednesday, February 10, 2010 7:00:00 AM (W. Europe Standard Time, UTC+01:00)
Sunday, April 26, 2009

I’ve had some problems with my Windows 7 Beta (Build 7000) installation. Windows Explorer keeps crashing (since so many things use Explorer functionality this is really annoying), still haven’t got ITunes to work (haven’t tried much though), the IE8 version that came with W7 was not, well… any good and a few other things. It’s Beta, so I wasn’t expecting it to be flawless.

May 5th however I’m hoping all these annoyances will silently go away, as the RC1 of W7 (Build 7100) will be publically available. I’m expecting it to appear on my MSDN Subscriber download anytime this week though.

Sunday, April 26, 2009 1:47:18 PM (W. Europe Daylight Time, UTC+02:00)
Tuesday, March 03, 2009

I’ve had some problems with my ATI display driver on Windows 7 on my HP Compaq 6910p. I did a search and found some new display drivers specifically for Windows 7. The installation didn’t work on my computer (it froze), but I found the MSI for the driver at this localtion:

C:\ATI\beta_w7-32_8-56-1-081203a-72489\Packages\Drivers\Display\LH_INF

That seamed to work.

I also have a Microsoft Wireless Notebook Presenter Mouse 8000 (nice short name) which didn’t work properly when presenting stuff in Power Point (the next button didn’t work). I found a Windows 7 driver for the mouse at Microsoft along with many others you might find interesting.

Tuesday, March 03, 2009 11:10:49 PM (W. Europe Standard Time, UTC+01:00)
Tuesday, June 03, 2008

Sysinternals Don't want to download and install all the tools from Sysinternals? Want to have access from anywhere on any computer? Just hook up to the UNC path: \\live.sysinternals.com\tools and you can run them directly. Thanks to John St. Clair for letting me know. Is that cool or what?

For more information about the different tools go to http://technet.microsoft.com/sysinternals.

Tuesday, June 03, 2008 8:36:07 PM (W. Europe Daylight Time, UTC+02:00)
Tuesday, May 13, 2008

Update: This article is not limited to deploying applications to Vista, but also when changing files that are only writeable by administrators (e.g. files in the Program Files directory).

If you have not made specific changes to your installation to support UAC in Vista, this is for you. I hope this will help others to not spend many days of confusion, desperation and sleepless nights like I have.

Lately I've been getting reports from some of my coworkers running Windows Vista that the app.config file in our application was not updated after installation. I've also experienced this myself. We've solved them without knowing exactly how (which I hate). Typically "I uninstalled the application and installed to a different location, and it worked!" Well, this is a workaround that are not particulary popular to any of our customers, so I dived into the problem to find the exact reason.

To save you some reading I'll just say that the reason and solution is to provide your application with a manifest file to handle UAC in Vista as described in this article: Create and Embed an Application Manifest (UAC) I haven't actually tried this out yet, but I trust the article to be correct :-)

Virtualization
But that's not the interesting part. The interesting part is what happens (or what can happen) if you don't have an application manifest for this purpose? If your superstitious you might think that something weird is going on with your computer. If you're like me you KNOW that something weird is going on with your computer, and you need to find it and fix it. The weird thing is Vista virtualization.

"File virtualization addresses the situation where an application relies on the ability to store a file, such as a configuration file, in a system location typically writeable only by administrators"

"Virtualization is implemented to improve application compatibility problems for applications running as a standard user on Windows Vista."

As I write this I have exactly this problem on my computer. I've installed our application (Contiki ECM) to this location: C:\Program Files\CMA Contiki AS\Contiki ECM\. This is where I've always install our app. So today I installed and checked that the app.config was updated with all my changes done during installation. And it hadn't. Actually it was updated, but not with my changes. It looked like an old file that I had some time ago. How could this happen?

Textpad .vs. Notepad
To make this even more confusing, I discovered this reading the file in TextPad, but when opening the file in Notepad it was fine. All my changes was there! So I thought that this was a TextPad problem. I started our application, but it turns out that when .Net tries to read the config file, it reads the same old stuff as TextPad did, resulting in old config to be loaded into our app. Why does Notepad get the right file? I don't know. Please tell me if you do.

The solution
So after Googling for a while I found this article on MSDN, and things started to make sense. But first let me show you what it looks like on my computer. The file causing my headaches are Contiki.Windows.Application.exe.config.

VistaUNCImg1 
Do you see when it's modified? 08:56 this morning, but the file that is being opened is from 13th of April! How do I know? Well, if you have a look at the virtualized files which you'll find in C:\Users\Username\AppData\Local\VirtualStore\[Your path], it might help out. So I looked at C:\Users\1jontor\AppData\Local\VirtualStore\Program Files\CMA Contiki AS\Contiki ECM and found this:

VistaUNCImg2 
Modified back in April. I opened this file and it was exactly what I saw in TextPad. But this file is the same both in TextPad and Notepad! :-)

Explorer gives you a shortcut to the Virtual Store folder if any files are virtualized, and will show this button in Explorer:

VistaUNCImg3

The end
A couple of notes from the MSDN article:

"When you enumerate resources in folders and in the registry, Windows Vista will merge global file/folder and registry keys into a single list. In this merged view, the global (protected) resource is listed along with the virtualized resource."

"The virtual copy will always be present to the application first.... even if [some file] is updated"

Even if the file is updated!? Who though of that? Was that really such a good idea? I can see what they where thinking, but it would have saved me a lot of work getting an error message saying "Access denied"...

To end this off I picked another good quote from the article:

"Microsoft intends to remove virtualization from future versions of the Windows operating system as more applications are migrated to Windows Vista."

I appreciate that... :-)

Tuesday, May 13, 2008 10:08:42 PM (W. Europe Daylight Time, UTC+02:00)
Sunday, December 23, 2007

iis7logoSP's are a necessity, but what I want to know is what have they done to improve IIS 7? Here's what the release notes for SP1 RC says:

IIS was included in some Windows Vista SKUs to enable web-based developers to write and test their applications. IIS in Windows Server 2008 is a significant server role which requires Internet-level scalability and performance requirements. The IIS7 components have gone through significant performance and reliability enhancements since Windows Vista originally shipped, in order to be a large-scale server component. These changes do not affect most Windows Vista users who do not even have the IIS7 components installed, however because Windows Vista and Windows Server are aligned, these changes are included in Windows Vista SP1.

You can find the "complete" change log here: http://technet2.microsoft.com/windowsvista/en/library/005f921e-f706-401e-abb5-eec42ea0a03e1033.mspx?mfr=true

So does this mean that there is a full UI and ftp support? The current IIS available in Vista is very limited by this. You can configure most of the stuff in config files (like I did with http redirect and logging bandwidth and referrers), but I would at least expect the features found in IIS 6 to be available from the UI in IIS 7. I've googled around to find some  more info, but nothing yet. I guess I'll have to install the RC to find out. Not sure if I want to risk it though...

IIS | Microsoft | Software | Vista | Windows
Sunday, December 23, 2007 12:59:30 AM (W. Europe Standard Time, UTC+01:00)

Windows Vista Logo Soon Windows Vista SP1 will be available for download. Or actually, it might even decide to automatically update itself, even though you specifically told it not to! However, not all of us want this to happen without our knowledge (or want to wait until some unexpected behaviors has been discovered), so Microsoft has release a service pack blocker. This blocker will also work for Windows XP and Windows Server 2003. The blocker only work for a set period of time. Mary Jo Foley has more details in her blog.

Sunday, December 23, 2007 12:02:52 AM (W. Europe Standard Time, UTC+01:00)
Saturday, August 11, 2007
InstallingUpdates.pngI just installed a new VM with Visual Studio 2008 and ran the Windows update to have a fully updated OS. There were 82 updates to download! About time to ship service pack 3? According to Mary Jo Foley, Microsoft have made a pre-beta available for testing and Microsoft says:
“We’re currently planning to deliver SP3 for Windows XP in the first half of CY2008. This date is preliminary, and we don’t have any more details to share at this time.”

Until then I'll rather wait for the download to finish than waiting for Service Pack 3 <smile>

Saturday, August 11, 2007 2:09:44 AM (W. Europe Daylight Time, UTC+02:00)
Thursday, July 12, 2007
Yes, it’s important to distinguish between the two. At the partner conference in Denver Kim Saunders (Senior Director, SQL Server Marketing) said that they launch SQL Server 2008 in February, but the actual release will be in Q2. And by launching they mean that they have all the marketing material and the final product information, but not the product.

As for Visual Studio and Windows Server I have not yet heard anything similar, so I'm still thinking 27th for these.
Thursday, July 12, 2007 4:10:11 PM (W. Europe Daylight Time, UTC+02:00)
RSS RSS - Comments Twitter LinkedIn
         
SEARCH
 
 
         
TOP POSTS
   
         
NAVIGATION
   
         
CATEGORIES
  .Net (61) ADFS (3) Agile (30) Ajax (5) Architecture (20) Articles (1) ASP.NET (6) ASP.NET-MVC (1) Blogging (12) Books (2) BPEL (1) CleanCode (1) CloudComputing (7) Community (4) CSharp (11) DasBlog (5) Database (2) DDD (5) Deployment (16) DSL (1) Events (38) ExtremeProgramming (6) Fun (6) Gadgets (4) IIS (10) InfoQ (4) Java (2) Lean (3) Linq (2) MemoryLeaks (5) Microsoft (37) MVC (1) NDC (2) NNUG (36) Other (10) Patterns (9) Performance (3) Scrum (17) Security (7) ServiceBus (1) Silverlight (4) Software (19) TeamManagement (11) TechEd (7) Testing (4) Tools (25) TvGuide (1) WCF (8) Web (15) WebDeploy (1) WIF (3) Windows (10) Vista (15) VisualStudio (16) WiX (9) Work (16) Workflow (3)  
         
ARCHIVE
   
         
BLOGROLL
   
         
ON THIS PAGE...
 
Using IIS7 And Application Request Routing as Load Balancer – Part 2
Using IIS7 And Application Request Routing as Load Balancer – Part 1
Looking Forward to May 5th and Windows 7 RC1
Drivers in Windows 7
Sysinternals tools on file share
Are you deploying applications to Windows Vista, and doing ok?
Windows Vista SP1 - IIS 7
Windows Vista SP1 - Blocker
Windows XP Service Pack 3?
SQL Server 2008 will not be released but launched