Creating an IIS Web Server Farm with DFSR and Shared Configuration

In a previous article we configured a single IIS webserver using powershell commands.

Now we want to add some additional servers that will run the same web-sites so that we can load balance incoming requests.

The first step is to create one or more additional web servers using the instructions in the previous article however in this case we don’t need to create folders, file shares or create any websites or application pools in IIS. We are going to sync all of that stuff from our master server using DFS Replication.

Installing DFS Replication on each web server

  • Install-WindowsFeature -Name FS-DFS-Replication -Confirm

Create WebFarmFiles Folder (if required) on each web server

  • New-Item -ItemType Directory -Path C:\WebFarmFiles

Install management tools on a Full GUI machine

Unfortunately the DFS management tools (even the powershell cmdlets) can only be installed on a Windows computer with a full GUI at this stage for some reason. Therefore, you will need to have another server (or workstation) that you can use to manage your DFS Replication Group. I am not sure why this is the case, but hopefully Microsoft fix it soon.

  • Install-WindowsFeature -Name RSAT-DFS-Mgmt-Con -Confirm
  • Get-DfsReplicationGroup this cmdlet should run once the tools are installed.

Create a DFS Replication Group

As we have been forced onto a Full GUI machine, you could do the DFS setup using the DFS Management console. Since we are having so much fun though let’s keep going with setting everything up via Powershell.

Run the following command from the Full GUI management machine. Replace ‘YourGroup’ and ‘your.domain’ with the relevant values and feel free to modify the description to suit.

  • New-DfsReplicationGroup -GroupName YourGroup -DomainName your.domain -Description
    "DFS Replication between YourGroup servers to sync content and configuration" -Confirm

Add Members to the DFSR Group

Run the following command for each ComputerName that needs to be added to YourGroup.
Add-DfsrMember -GroupName YourGroup -ComputerName WEB0X -Confirm

Add DFS Replicated Folder

  • New-DfsReplicatedFolder -GroupName YourGroup -FolderName WebFarmFiles -Confirm

Add Connections between web servers

The command below creates a bi-directional connection between the servers WEB01 and WEB02. You can configure various configurations with this command, for example you may like a ‘hub and spoke’ type setup where WEB02, WEB03 etc are all connected to WEB01 but not each other. You might also choose to connect each server with every other server in more of a ‘full mesh’ setup. ie (WEB01 <-> WEB02, WEB01 <-> WEB03 AND WEB02 <-> WEB03).
Add-DfsrConnection -GroupName YourGroup -SourceComputerName WEB01 -DestinationComputerName WEB02 -Confirm

Configure the Primary server’s membership (and set the Staging Quota to 8GB)

  • Set-DfsrMembership -GroupName YourGroup -FolderName WebFarmFiles -ContentPath C:\WebFarmFiles -StagingPathQuotaInMB 8192 -ComputerName WEB01 -PrimaryMember $true -Confirm

Configure the other members

  • Set-DfsrMembership -GroupName YourGroup -FolderName WebFarmFiles -ContentPath C:\WebFarmFiles -StagingPathQuotaInMB 8192 -ComputerName WEB02, WEB03 -Confirm

Associated cmdlets to explore:
Get-DfsrBacklog -GroupName YourGroup -SourceComputerName WEB0X -DestinationComputerName WEB0Y
More here:
Get-EventLog -LogName 'DFS Replication' -Newest 20 to check for DFSR errors
Get-EventLog -LogName 'DFS Replication' -Newest 20 | Format-List message for full message details
Restart-Service -Name DFSR this may need to be run on all existing servers after adding a new member to the group

Exporting IIS Configuration for Sharing

On the initial web server that we set up in the last article, you should already have a website and application pool set up. Rather than creating all of those settings again, let’s export the configuration so that we can use it on all of our web servers. Placing this file in our DFS folder will ensure that all of the web servers stay in sync as configuration changes are made.
New-Item -ItemType Directory -Path C:\WebFarmFiles\Configuration
$KeyEncryptionPassword = ConvertTo-SecureString -AsPlainText -String "SecurePa$$w0rd" -Force
Export-IISConfiguration -PhysicalPath "C:\WebFarmFiles\Configuration" -KeyEncryptionPassword $keyEncryptionPassword

You should now have 3 files in the C:\WebFarmFiles\Configuration folder.

Enabling IIS Shared Configuration

Now that our IIS configuration from the initial server has been exported. All of our web servers (including the initial server) need to be set to look at our Shared Configuration files. As DFS is handling the synchronisation of these files between our servers, we can simply point each one to the C:\WebFarmFiles\Configuration folder and they will all be able to read and write changes to the configuration. On each server, run:
$KeyEncryptionPassword = ConvertTo-SecureString -AsPlainText -String "SecurePa$$w0rd" -Force
Enable-IISSharedConfig -PhysicalPath "C:\WebFarmFiles\Configuration\" -KeyEncryptionPassword $KeyEncryptionPassword

And that’s pretty much it. Your web servers should now all be up and running with the same sites that you had configured on the initial server. You can test each one by updating your hosts file to point to the individual IP address of each server and testing in the browser one by one. And obviously the next step from here is to configure a load balancer like HAProxy or NGINX to direct traffic across all of the servers in a fair and reasonable fashion. Stay tuned for the next episode.

Install and configure IIS on Windows Server Core 2016

In a previous post we covered using the System Preparation Tool to convert a VM into a VM Template in XenServer. Once we have used this template to create a new VM, it’s time to set it up as an IIS web server to host some ASP.Net MVC applications.

Revisiting the Basics

Network Settings

When creating a new VM from the template the network settings in the template will also be copied. If it was set to DHCP that will be fine but if the template had a static IP, you should change the IP address to a different one now so that you don’t run into an IP conflict (ie. Two machines on the network using the same IP address).
start powershell
– Select 8) Network Settings
– Select the relevant Network Adapter from the list
– Select 1) Set Network Adapter Address
– Enter S for (S)tatics
– Enter the static IP address
– Enter the subnet mask
– Enter the default gateway
– If required select 2) Set DNS Servers

Advanced Networking

In some cases you may need to get a little more fancy with your networking. For example you may need to set your default gateway to a gateway router that can get your traffic out to the Internet, but you have a backend gateway router that handles communication to IP addresses on your private LAN. In this case you can use the route command to tell Windows to send traffic out through different gateway routers.
route print will show current routes, note the current default gateway route (
route add mask 10.x.x.x -p will send all traffic destined for IP addresses in the subnet (ie. Any address starting with ’10.’) out through the 10.x.x.x IP address (backend gateway router). The -p signifies that the route will be persistent and therefore will stick around after a reboot.
route print will now show your new persistent route both in the Active Routes section and below that under Persistent Routes.

Now that you have this route to the private LAN in place, you can change the default gateway address to the ‘Internet’ gateway server without loosing access to your server over the private LAN. This can be done by reconfiguring the network settings again using sconfig or by simply deleting the default route and adding another one.
route delete
route add mask 10.y.y.y -p will send all traffic destined for an IP that can’t be handled by a more specific route out via the 10.y.y.y router. In this case you would replace the 10.y.y.y with the IP address of your Internet gateway router.

Enable Echo Requests (pings)

This step is optional but if you are going to monitor your server with something like Nagios you probably want to make sure it is online. This will enable the default rule to allow inbound IPv4 pings.
Set-NetFirewallRule -Name FPS-ICMP4-ERQ-In -Enabled True

Checking Internet Access

Many websites rely on web based resources (API’s etc). Now would be a good time to check that your new server has Internet access (unless you are purposely restricting it).
Invoke-WebRequest -UseBasicParsing

This will show a big red error if it can’t hit Google, or a 200 status code if it can.

Join an Active Directory Domain

If you need to join your server to a domain to make management easier, follow these steps otherwise continue on to the next section to install IIS.
– Select 2) Computer Name
– Set the new computer name and reboot the server
– After the reboot completes, log in again with the Administrator user
– Select 1) Domain/WorkGroup
– Type D for (D)omain
– Enter the name of the domain you wish to join and the relevant administrator credentials
– You will be prompted to change the computer name again, click No as we have already done this.
– Click Yes on the Restart prompt
– After rebooting users should be able to login with your domain credentials.

Switching users on the Server Core login screen

If you are using Remote Desktop you should have a normal sign in experience but if you are still looking at the server’s console with just a CMD window on screen, it may not be immediately obvious how to switch users to log in with your domain credentials instead of the default administrator account. Here’s how:
– To change users hit the ESC at the LoginUI.exe screen
– This will present another sign-on options screen, hit ESC again
– Select Other User
– Enter your domain credentials and log in.

Installing the Web Server Role

Powershell comes with some very useful tools for managing the Window Features that are installed on a server
start powershell to open a powershell window
Install-WindowsFeature -Name Web-Server -Confirm will install IIS.
Get-WindowsFeature will show you a list of all available features and show which are installed.

At this point you should have a base install of IIS running the default website on port 80. If you open a browser and type in the IP address of the server you should see the default IIS website.

Install ASP.NET Support

  • Install-WindowsFeature -Name Web-Asp-Net45, Web-Net-Ext45 -Confirm

Installing IIS Diagnostic, Performance and Security Goodies

  • Install-WindowsFeature -Name Web-Custom-Logging, Web-Log-Libraries, Web-Request-Monitor, Web-Http-Tracing -Confirm
  • Install-WindowsFeature -Name Web-Performance -IncludeAllSubFeature -Confirm
  • Install-WindowsFeature -Name Web-Security -IncludeAllSubFeature -Confirm

Installing and Enabling Remote Management for IIS

This will allow us to use the IIS Manager window on another computer to manage our server. Even though we’re installing this now, I won’t be using it to configure the server in the interest of trying to do as much as possible via powershell. The idea is to script all of the server setup so that it can be entirely automated.
Install-WindowsFeature -Name Web-Mgmt-Service -Confirm
Set-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\WebManagement\Server\ -Name EnableRemoteManagement -Value 1
Set-Service -Name WMSvc -StartupType Automatic
Start-Service -Name WMSvc

Note: You will need to install the IIS Manager on the machine that you will be using to manage the server/s. To do this, run:
Install-WindowsFeature -Name Web-Mgmt-Tools -Confirm

Website File Structure

The default directory for storing website files for IIS is C:\inetpub\wwwroot. When configuring your websites though you can put the files wherever you like. To make things simpler if you want to sync your website files between multiple web servers or apply special permissions etc, I find it best to store files in a seperate folder.

To keep things organise when hosting multiple websites across multiple domains I like to organise the content on my IIS servers in the following folder structure:


So if you have a site that will live at the URL then blah.aspx would be saved to the C:\WebFarmFiles\Content\\subdomain1\project1\ folder.

This setup may look a little confusing at first but it will make sense if/when you need to host multiple sites and quickly find things. Of course your system of organising files may vary and it is, of course, personal preference.

  • New-Item -ItemType Directory C:\WebFarmFiles\Content\\subdomain1 this should create all the required parent folders for us automatically.

Getting files onto the server

Create Network Share

  • New-SmbShare -Name WebFarmFiles -Path C:\WebFarmFiles -FullAccess "domain\group1", "domain\group2"
  • Copy files from another machine onto this one using the share \\server\WebFarmFiles.

You could also use robycopy or other utilities to copy files from another network share or download files from github etc.

Set up your first Website

Let’s say we copied some files to \\server\WebFarmFiles\Content\\subdomain1 which are intended to be accessed at the URL Let’s also say that we want this website to run in it’s own Application Pool so that we can manage it’s resource usage easily rather than everything running in the DefaultAppPool

Create the IIS Application Pool

  • New-WebAppPool -Name

Associated cmdlets to explore:
Get-WebAppPoolState | Select *
Restart-WebAppPool -Name

Change the App Pool Identity

In some cases, the process running your application may need to access files on the network with specific user permissions.
Set-ItemProperty IIS:\AppPools\app-pool-name -name processModel -value @{userName="domain\user";password="password";identitytype=3}

Set the App Pool startMode

If your application is a big one, you may wish to set it to AlwaysRunning so that the first visitor doesn’t have to wait for it to initialise:
Set-ItemProperty IIS:\AppPools\app-pool-name -Name startMode -Value AlwaysRunning
Get-ItemProperty IIS:\AppPools\app-pool-name -Name startMode to check the setting.

Create the IIS WebSite

  • New-Website -Name -ApplicationPool -HostHeader -PhysicalPath C:\WebFarmFiles\Content\\subdomain1\

Associated cmdlets to explore:
Remove-WebSite -Name
Stop-Website -Name
Start-Website -Name

The new website should now be running and you can access it by pointing the URL at your servers IP address either just from your local machine by modifying your hosts file or by modifying the DNS records for the domain. These methods are not covered in this article.

Adding an additional binding

In some cases you may have a need to point two different URL’s at the same website.

  • New-Binding -Name -HostHeader

In this case, the ‘Name’ of the binding relates to the WebSite it will be linked to.

Associated cmdlets to explore:
Get-WebBinding | Select-Object * for a more advanced view
Remove-WebBinding -HostHeader

Windows Server Core 2016 Initial (XenServer) Template Setup

After installing Windows Server Core 2016 you might wander what to do with yourself next. If, like most people, you have always used Windows via the GUI then you are entering a whole new world. Being presented with only a CMD window on startup will be a little daunting at first. But you will learn how to drive it with a little practise. Here are some tips to get you started with configuring your first Server Core install and converting it to a Template so that you can create many more instances.

server core first command
The Windows Server Core 2016 User Interface

Launching Programs

As you have probably already noticed, Windows Server Core does still have a GUI of sorts. There is still a desktop that the CMD window sits on. You can also still open and run programs. For example:
notepad will launch a notepad window.
taskmgr will launch the Task Manager.
powershell will launch a powershell session (in the current CMD window)
start powershell will launch a seperate powershell window.

server core programs
Programs running in Windows Server Core 2016

These programs can still be minimised and maximised, they just don’t sit on a ‘Task Bar’. Instead they just minimise down to small tiles that live along the bottom of the screen. For those of you that used Windows 3.1 you will remember how this works (showing my age here).

minimised programs on server core
Minimised programs on Windows Server Core 2016

Installing XenTools

  • Insert the XenTools ISO into the VM via XenCenter
  • start powershell to open a seperate powershell window because it’s much more… powerful.
  • cd d: to change to our CD drive (replace d: with whatever letter your CD drive would be)
  • start .\Setup.exe to launch the setup wizard. Even though we have no GUI, this will still run like it always has.
  • Run through the wizard selecting the usual options. I usually disable the automatic updates for better control.

Configuring the Basics

The ‘Server Configuration’ command line utility is a great way to configure the basic settings on your server to get it on the network and connected to your domain etc. This screen may just handle the bulk of the configuration that you require on your server. You can launch it from CMD or powershell by typing sconfig.

Windows Server Configuration Utility Main Menu

Network Settings

  • sconfig
  • Select option 8) Network Settings
  • Follow the prompts to configure your network adapters

Remote Desktop

  • sconfig
  • Select option 7) Remote Desktop
  • At this point you should be able to connect to the VM via XenCenter’s Remote Desktop console or any orther RDP client.

Windows Updates

  • sconfig
  • Select option 6) Download and Install Updates
  • Follow the prompts to install your updates.

NB: If you are behind a firewall or on a private network with no Internet access, you may need to point your VM at a WSUS server.

Configuring Windows Updates to point to a WSUS Server

If you have a WSUS server on your LAN, you can configure the VM to use it by substituting the relevant address into the commands below. For example for servers on Softlayer/IBM’s private LAN you can use This may not be required if you push out the WSUS settings via a Group Policy on your domain. I always like to do updates before I join VM’s to the domain though, just out of habit (best practise?).

  • start powershell
  • Set-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -Name WUServer -Value http://your.wsus.hostname
  • Set-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -Name WUStatusServer -Value http://your.wsus.hostname
  • Set-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -Name UseWUServer -Value 1
  • To check that these registry settings have all saved properly you can use the powershell Get-Item commandlet:
  • Get-Item -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate
  • Get-Item -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU
  • If you re-run the Windows Updates in sconfig now you should now pull updates from the WSUS server.

In the old ‘GUI’ days, this would have done this by opening MMC, adding the Group Policy Snap-in and then finding the policies that control the registry keys we are editing here. MMC does not come with Server Core but you can connect to it from a remote ‘full install’ windows machine that has MMC. There is some setup required to make this work however which I won’t cover here.

Converting the VM to a Template (SysPrep)

To convert this VM to a template we need to ‘reset’ Windows using the System Preparation Tool. This will mean that when we clone the VM Template we will be creating a fresh new VM rather than a copy of the existing one with the same hostname etc.

System Preparation Tool
  • start powershell
  • C:\Windows\System32\Sysprep\sysprep.exe
  • Under System Cleanup Action select Enter System Out-of-Box Experience (OOBE)
  • Tick Generalize
  • Under Shutdown Options select Shutdown
  • Wait for the VM to completely shutdown
  • In XenCenter, right click the VM
  • Select Convert to Template…
  • Click Convert
  • The template is now ready to be used to create new VM from

Creating a new VM

  • In XenCenter, click VM (Top Menu)
  • Select New VM…
  • Select the template you just created
  • Continue through the wizard selecting the relevant options.

In the next post I’ll show you how to configure our new VM as an IIS server.