Getting Started with DFSN and PowerShell

DFS is a really cool feature. There are two parts to DFS: Namespace and Replication. They do different jobs, and can be thought of as different roles. DFS Namespace is designed to create a unified UNC path, where subfolders can be links to different serves and shares. The servers linked-to can be assigned costs and placed into sites.

Example

Here’s an example:

Let’s say I have 5 file servers and shares:

  • OH-FS1
    • \\oh-fs1\hr
    • \\oh-fs1\finances
  • OH-FS2
    • \\oh-fs2\software
  • OH-FS3
    • \\oh-fs3\public
  • CA-FS1
    • \\ca-fs1\hr
    • \\ca-fs1\finances

It can be confusing for a user to remember what file server they need to go to. DFS Namespaces can help us unify the structure into this:

  • \\mycorp.com\
    • files\
      • software
      • public
      • finances
      • hr

Then, we can configure DFS Namespaces so that if you’re at the CA site, accessing \\mycorp.com\hr will redirect you to \\ca-fs1\hr. Conversely, we can configure this namespace so that accessing \\mycorp.com\hr from the OH site will redirect the user to the share \\oh-fs1\hr. This is incredibly cool.

You might be wondering, what good is it to redirect people to servers in different sites if they won’t see the same data? For example, what if the HR folk at the OH and CA site want to collaborate via the ‘hr’ share? This is what DFS Replication is for. It will be covered in a different post.

Getting Started

Let’s walk through the creation of a DFS Namespace.

Our final namespace will look like this:

  • \\contoso.com\files\
    • hr
    • software
    • finances
    • public

The following shares will be on a server named fs1: hr, finances, software. The share ‘public’ will be on a server named fs2.

  1. Install two file servers: fs1 ans fs2.
  2. Configure the file servers normally and join them to the domain.
  3. Run the following PowerShell code on both file servers to install the DFS Namespace feature:
    Install-WindowsFeature FS-DFS-Namespace -IncludeManagementTools
  4. Run the following PowerShell code on fs1 to create a 1-server namespace.
    #Create the SMB share folders:
    $folders = @("C:\DFSRoots\Files","C:\shares\hr","C:\shares\finances","C:\shares\software")
    $folders | mkdir
    
    #Create the shares
    $folders | %{sharename = (GC $_).name; New-SMBShare -Name $shareName -Path $_ -FullAccess "contoso\administrator"}
    
    #Create the DFS Root
    New-DfsnRoot -Path \\contoso.com\files -TargetPath \\fs1\files -Type DomainV2
    
    #Create the DFS Folders for fs1
    $folders | ?{$_ -like "*shares*"} | % {$name = (gc $_).name; $DfsPath = ("\\contoso.com\files\" + $name); $targetPath = ("\\fs1\" + $name);New-DfsnRootFolder -Path $dfsPath -TargetPath $targetPath}
    
  5. At this point, fs1 is configured. In order to add shares from fs2 into the DFS Namespace, we first need to configure fs2 to host the ‘files’ namespace. Run the following PowerShell code on fs2.
  6. $folders = @("C:\DFSRoots\Files","C:\shares\public")
    $folders | mkdir
    
    #Create the shares
    $folders | %{sharename = (GC $_).name; New-SMBShare -Name $shareName -Path $_ -FullAccess "contoso\administrator"}
    
    #Host the DFS Root
    New-DfsnRootTarget -Path \\contoso.com\files -TargetPath \\fs2\files
    
    #Create the DFS Folders for fs2
    $folders | ?{$_ -like "*shares*"} | % {$name = (gc $_).name; $DfsPath = ("\\contoso.com\files\" + $name); $targetPath = ("\\fs1\" + $name);New-DfsnRootFolder -Path $dfsPath -TargetPath $targetPath}
    

Note that we don’t need to run New-DfsnRootTarget on fs2, but the SMB Shares ‘files’ and ‘public’ must be configured on fs2 before we can add the fs2 shares as targets on the \\contoso.com\files namespace.

And that’s it! You can now browse the tree from a client or the servers, and you’d never know that the folders are on different servers.

Advertisements

Getting Started with SQL 2012 Clustering

I’ve been playing with SQL Clustering recently. Why? It’s cool! Here’s how to get it up and running quickly.

Overview

  1. Create an MSCS Failover Cluster with 2 nodes.
  2. Install the SQL Cluster role.
  3. Configure the SQL nodes.
  4. Install the MS DTC cluster role.
  5. Test MSDTC

Create an MSCS Failover Cluster

To do this, see my previous post Windows Server 2012 – Getting Started With Failover Clustering. Your cluster will need the following characteristics:

  • Quorum disk configured.
  • A free cluster disk for DTC use.
  • A free cluster disk for SQL use.

Install the SQL Cluster Role

Here are the steps:

Create the Service Accounts

#read-host must be done manually or it assumes that the lines following it are the input.
$cred = Read-Host "Account Password:" -AsSecureString
$namePrefix = "sqlc1-"
$accounts = @("ssa","ssde","ssrs","ssis")
$accounts | %{$newname = $namePrefix + $_; New-ADUser -name $newname -Enabled $true -AccountPassword $cred}

Install .Net 3.5

  1. Insert windows media.
  2. Run the following PowerShell code:
    Install-WindowsFeature net-framework-code -source D:\windows\sxs

Install SQL Node 1

Steps:

  1. Insert SQL media
  2. Run the install wizard.
  3. Choose Installation -> New SQL Server Failover Cluster Installation

Here are my install notes:

  • On the screen ‘Setup Support Rules’, you will likely see warnings for MSDTC, MSCS, and Windows Firewall. This is OK.
  • On the screen ‘Instance Configuration’, enter the desired netbios name of your cluster under ‘SQL Server Network Name’. Don’t worry about the instance root directory being on a non-cluster disk. The instance root that you see under ‘Instance Root Directory’ is not where the databases will actually be stored.
  • On the screen ‘Cluster Resource Group’, you will see a sheet with two red circles in the ‘qualified’ column. This is normal, just hit ‘next’.
  • On the screen ‘Cluster Disk Selection’, check the box next to the cluster disk that you’d like to use for the SQL database. We will need to leave at least 1 disk free for MSDTC, so don’t check the boxes next to all of the cluster disks. Leave one available.
  • On the screen ‘Cluster Network Configuration’, check the box for the cluster network you’d like to use. I recommend entering a static address. The cluster will auto-register its name with DNS, but if you want to use TCP/IP you will need to enter specific IP’s into SQL Server Configuration Manager on each node.
  • on the screen ‘Server Configuration’, enter the username\passwords for the service accounts created in a previous step. Leave the ‘startup type’ as the default for all services (most should be set to ‘manual’).

Verify that the SQL Role is online using Failover Cluster Manager. Then, verify that you can connect to the SQL Cluster Network Name using SQL Server Management Studio (from the node itself since we haven’t configured TCP). If it connects, then your first node is up. Congrats!

Install SQL Node 2

There is nothing substantially noteworthy about adding the second node. The installation wizard is streamlined and straightforward.

  1. Insert SQL media.
  2. Run the install wizard.
  3. Choose Installation -> Add Node to a SQL Server Failover Cluster

Configure TCP and Firewalls

On both nodes, do the following:

  1. Launch SQL Server Configuration Manager
  2. Navigate to SQL Server Network Configuration -> Protocols for MSSQLSERVER
  3. Right click TCP/IP and choose ‘Properties’.
  4. On the ‘IP Addresses’ tab, make sure that the IP addresses for the cluster nodes and the SQL Cluster network resource are entered and enabled.
  5. Close SSCM.
  6. Open Powershell and run the following commands to open the firewall. I recommend choosing a firewall rule more specific than the one I’m presenting here, but it will get you started.
    New-NetFirewallRule -DisplayName "MSSQL BROWSER UDP" -Direction Inbound -LocalPort 1434 -Protocol UDP -Action Allow -Profile Domain
    New-NetFirewallRule -DisplayName "MSSQL ENGINE TCP" -Direction Inbound -LocalPort 1433-1434 -Protocol TCP -Action Allow -Profile Domain
    

You should now be able to connect to the SQL Server Cluster network name from any domain computer. Pretty awesome.

Install the MS DTC Cluster

I didn’t know anything about the Microsoft Distributed Transaction Coordinator service until this SQL clustering adventure. Here’s some background information.

  1. (wikipedia) Microsoft Distributed Transaction Coordinator
  2. What exactly is MSDTC, any when do I need it?
  3. How to install a clustered SQL Server 2012 Instance – step-by-step – Part 4

Basically, it’s a service that handles transactions across multiple nodes. Some applications as well as SQL services require MSDTC. I’m choosing to cluster it even though I’m not absolutely sure it’s necessary. Here’s how to set it up.

First, copy the following PowerShell code. Scan through and replace any strings with the ones you’d like to use.

#Add DTC Role
Add-ClusterResource "sqlc1-dtc" -ResourceType "Distributed Transaction Coordinator" -Cluster cluster1 -Group "SQL Server (MSSQLSERVER)"

#DTC Depends on Network Name
##find the name of the network name resource with Get-ClusterResource
##example: $sqlNetworkName = "SQL Network Name (sqlc1)"
$sqlNetworkName = "Insert SQL Cluster Network Resource Name Here"
Add-ClusterResourceDependency "sqlc1-dtc" $sqlNetworkName -Cluster cluster1

#Add DTC Disk to DTC Group
##chose a cluster disk. 1GB freespace is fine. It just stores some logs.
Move-ClusterResource "Cluster Disk 2" -Cluster Cluster1 -Group "SQL Server (MSSQLSERVER)"

#DTC Depends on Disk
Add-ClusterResourceDependency "sqlc1-dtc" "Cluster Disk 2" -Cluster cluster1

#SQL Server Depends on DTC
Add-ClusterResourceDependency "SQL Server" "sqlc1-dtc" -Cluster cluster1

In order to get DTC working between nodes, I needed to open all firewall ports between the DTC nodes themselves, and between the DTC nodes and the application server. I’m sure there’s a better way to do this. Again, this will get you started.

In powershell, on each node:

#$IPAddresses = @("node1-IP","node2-IP","Test-Client-IP")
$IPAddresses = @("10.10.10.10","10.10.10.50","10.10.10.54")
New-NetFirewallRule -name clustering-rpc-ports-to-partners -remoteaddress $IPAddresses -displayname "Clustering - Allow RPC to Partners"

Finally, we need to enable network access for the DTC service. To do this, complete the following procedure:

  1. Logon to the node actively running the DTC role.
  2. Run the ‘Component Services’ snap-in from ‘Control Panel’ -> ‘Administrative Tools’.
  3. Navigate to ‘Component Services’ -> ‘Computers’ -> ‘My Computer’ -> ‘Distributed Transaction Coordinator’ -> ‘Clustered DTCs’.
  4. Right-click the DTC cluster and choose ‘Properties’.
  5. On the ‘Security’ Tab, choose the following checkboxes:
    [X] Network DTC Access
    [X] Allow Remote Clients
    [X] Allow Inbound
    [X] Allow Outbound
  6. Click ‘OK’, then restart the SQL failover cluster via the Failover Cluster Management tool.

Assuming all went well, you now have DTC configured. Let’s test it!

Testing the DTC Cluster

Download the following tools from Microsoft. Extract them to a temp directory of your choice on both cluster nodes, and on a test client.

  • DTCPing
  • DTCTester

Testing Basic Connectivity

Perform the following procedure to test DTC basic connectivity:

  1. Launch DTCPing on both DTC nodes.
  2. On node1, type the netbios name of node2 into the DTC ping utility and press ‘Start’.
  3. You should see a successful response.
  4. Try this from the test client also, after relaunching DTCping on the nodes.

If DTC ping fails, it’s probably a name resolution or network issue.

Testing Actual Transactions

Perform the following procedure to test actual DTC transactions:

  1. On node1, naviagte to Control Panel -> Administrative Tools -> ODBC Connectors (32-bit).
  2. Create a new System DSN pointing at the netbios name of the SQL cluster.
  3. Enable mixed-mode authentication on the SQL cluster via SQL Server Management Studio.
  4. Create a new SQL account on the SQL cluster named ‘test’. Give it full permissions on the databases and cluster via SQL Server Management Studio.
  5. Run DTCTester.exe with the following syntax:
    dtctester.exe <dsn-name> <user> <password>
    example: dtctester.exe sqlc1-dsn test myPassword

You can perform the same procedure from a test client instead of a node, however there are additional steps required.

On a test client, perform the following steps before running DTCTester.exe

  1. Install DTC with the following powershell command:
    DTCInstall
  2. Navigate to Control Panel -> Administrative Tools -> Component Services.
  3. Navigate to ‘Component Services’ -> ‘Computers’ -> ‘My Computer’ -> ‘Distributed Transaction Coordinator’ -> ‘Clustered DTCs’.
  4. Right-click the DTC cluster and choose ‘Properties’.
  5. On the ‘Security’ Tab, choose the following checkboxes:
    [X] Network DTC Access
    [X] Allow Inbound
    [X] Allow Outbound

If dtctester.exe fails, follow the chart at this page: Troubleshooting MSDTC Communication Checklist.

Now, you can create the DSN on the test client and run dtctester.exe

Whew, and now you’ve got a working SQL cluster with DTC. Not the easiest thing ever. Easier than getting vPro running at least ;).

Windows Server 2012 – Getting Started With Failover Clustering

Failover clustering is a bit intimidating at first. However, once you get started it’s not too bad (like most things).

Overview

  1. Configure VM’s
  2. Configure Shared Storage
  3. Configure Nodes
  4. Create the Cluster

Configure VM’s

You will need the following VM’s to do this in a lab:

  1. iscsi1. This server will act as the iSCSI target.
  2. clusternode1.
  3. clusternode2.

I’ll leave the names and addressing up to you. For help creating VM’s in Hyper-V, see my previous blog post Getting Started with Hyper-V.

Configure Shared Storage

You’ll need to create the following volumes and connect them to both cluster node’s.

  1. cluster1-quorum, 5GB
  2. cluster1-disk1, 10GB

For help with configuring an iSCSI target server, see my previous blog post Windows Server 2012 – Getting Started With the iSCSI Target Server.

Configure the Nodes

On each node, run the following commands. You’ll need to scan the code and replace variables as needed. For example, “Target-IQN” needs replaced with the correct setting from the iSCSI target server.

#Install Roles
Install-WindowsFeature failover-clustering,multipath-io -includeManagementTools

#Configure iSCSI Service
Start-Service msiscsi
Set-Service msiscsi -startupType "Automatic"

#Connect to the Target
New-iSCSITargetPortal -TargetPortalAddress "iscsi target fqdn"
$nodeAddress = (Get-IscsiTarget).NodeAddress
Connect-iSCSITarget -NodeAddress $nodeAddress -IsPersistent $true

#Configure Multipath Settings
Enable-MSDSMAutomaticClaim -BusType iSCSI #(computer will reboot, possibly bsod)
Restart-Computer

##one the reboot is complete, continue with the code below.

Get-MSDSMAutomaticClaimSettings #visually confirm that iscsi = $true
Set-MSDSMGlobalDefaultLoadBalancePolicy -Policy RR

#Online and Initialize the Disks
Get-Disk | ?{$_.FriendlyName -like "MSFT Virtual HD*" -and ($_.IsReadOnly -eq $true -or $_.isOffline -eq $true)} | % {Set-Disk -Number $_.Number -IsOffline $false}
Get-Disk | ?{$_.FriendlyName -like "MSFT Virtual HD*" -and ($_.IsReadOnly -eq $true -or $_.isOffline -eq $true)} | % {Set-Disk -Number $_.Number -IsReadOnly $false; Initialize-Disk -Number $_.number -partitionStyle GPT}

Now, choose one cluster node to work on. Login and run the following commands:

#Format the disks and assign a drive letter
Get-Disk | ?{$_.FriendlyName -like "MSFT Virtual HD*" -and $_.partitionstyle -eq "RAW"} | % {
  Initialize-Disk -number $_.number -partitionStyle GPT
  New-Partition -disknumber $_.number -useMaximumSize -AssignDriveLetter
  $driveLetter = $null
  $driveLetter = (Get-Partition -DiskNumber $_.number | ?{$_.type -eq "Basic"}).DriveLetter
  Format-Volume -DriveLetter $driveLetter -FileSystem NTFS
}

#Run a test to see if the cluster can be created.
Test-Cluster -node sql1,sql2 -ReportName C:\Install_Files\cluster1.report.html
#stop here and review report. Some warnings are ok.

#create the new cluster
New-Cluster -name cluster1 -node clusternode1,clusternode2 -staticAddress 10.10.10.20 -NoStorage -AdministrativeAccessPoint ActiveDirectoryAndDns

#add the volumes to the cluster
Get-ClusterAvailableDisk -cluster cluster1 | Add-ClusterDisk

#run this to find the cluster disks. Choose one to be the quorum.
Get-ClusterResource

#configure quorum settings. change "cluster disk 1" to whatever disk you want to be the quorum.
Set-ClusterQuorum -Cluster Cluster1 -NodeAndDiskMajority "Cluster Disk 1"

And, that’s it. You should now have a green cluster to play with.

Windows Server 2012 DHCP Clustering

Getting Started with Windows DHCP on Server Core

At work, we currently switched from a Linux dhcpd server to a Windows 2012 R2 DHCP cluster. Here’s how I built the cluster.

What to Know:

  • Windows DHCP Clustering does not require Microsoft Failover Clustering (MSCS).
  • Windows DHCP Clustering will synchronize leases, but it will not synchronize scope options or reservations. To do that, you’ll have to use PowerShell.

The Basics

  1. Install and Authorize the DHCP role on two nodes.
  2. Create a scope.
  3. Create a failover partnership.
  4. Synchronize scope options with PowerShell.

Step-By-Step

Install and Authorize the DHCP servers.

Login to each server (preferably with PS Remoting) and run the following command in PowerShell.

Install-WindowsFeature DHCP –IncludeManagementTools
#Authorize
Add-DhcpServerInDC

Configure the DHCP servers.

Login to one of the servers, and run the following code after modifying it for your needs.

#add some scopes!
Add-DhcpServerv4Scope -Name "Network 1" -StartRange 10.10.10.1 -EndRange 10.10.10.254 -SubnetMask 255.255.255.0
Add-DhcpServerv4Scope -Name "Network 2" -StartRange 10.10.20.1 -EndRange 10.10.20.254 -SubnetMask 255.255.255.0

#configure failover for the scopes
Add-DhcpServerv4Failover -ComputerName <dhcpServer1-FQDN> -PartnerServer <dhcpServer2-FQDN> -Name "server1-server2" -ScopeId <Scope – ex: 10.10.10.0,10.10.11.0> -SharedSecret "Password"

#configure some DHCP options on one of the servers (note: does not auto-replicate).
Set-DhcpServerv4OptionValue -DnsDomain <option-15-domain-name> -DnsServer <option-5-dns-servers> [-optionId <ID#> -Value <"IdValue">]
Set-DhcpServerv4OptionValue –ScopeID <10.10.10.0> –Router <10.10.10.1> [-optionId <ID#> -Value <"IdValue">]

References

Sync DHCP Options

You will soon notice that DHCP options are not automatically synchronized. Here’s a microsoft blog article about the issue.

What to know about the Microsoft DHCP Sync Tool:

  • It launches at startup via task manager and then runs in the background.
  • The tool should be installed on one DHCP server only.
  • Any changes to DHCP should be done on the server where the DHCP Sync Tool is installed.
  • The DHCP Sync Tool will not delete scope options.
  • The DHCP Sync Tool will not synchronize server-level options.
  • If new scopes are created after the sync tool is launched, the tool will not synchronize changes to the new scopes until the tool is restarted.

It’s not a perfect tool, but it works well for what it does (scope synchronization). I’m planning on double-checking changes I make anyway.

  1. Download the DHCP Config Automatic Sync Tool from Microsoft.
  2. Extract the zip file to your desired destination folder (ex: C:\scripts\dhcpSync).
  3. Open powershell and navigate to the extracted tool folder.
  4. Run .\install.ps1.
  5. Open Task Manager, navigate to Microsoft -> DHCP Server.
  6. Right-click the newly created task and choose ‘Run’.

You’re now sync’ing. Grats!

Server 2008 Enterprise Subordinate CA Install Scripts – Part 3 – DFSR

It’s important that the inetpub directories of both Subordinate CA’s are synchronized. We can use DFSR to do this!

Overview

  • Part 1 – Installing ADCS
  • Part 2 – Installing IIS 7
  • Part 3 – Installing DFSR
  • Part 4 – Installing Certificate Web Enrollment Pages
  • Part 5 – Installing CES\CEP
  • Part 6 – Installing an OCSP Responder Array

Scripts!

File 1 – Install-DFSR.cmd

REM Install and Configure DFSR for IIS Content Repl
Powershell -executionpolicy bypass -command "Import-Module ServerManager; Add-WindowsFeature File-Services,FS-DFS,FS-DFS-Replication"
dfsradmin RG New /rgname:"CDP Replication Group"
dfsrAdmin RG Set Schedule full /RGName:"CDP Replication Group"
dfsradmin member new /rgname:"CDP Replication Group" /memname:%computername%
dfsradmin RF New /rgName:"CDP Replication Group" /RfName:CertData
dfsradmin Membership Set /RgName:"CDP Replication Group" /RfName:CertData /MemName:%computername% /LocalPath:F:\inetpub\wwwroot\CertData /MembershipEnabled:true /IsPrimary:true

REM Set staging directory
IF NOT EXIST "G:\DFSR" MKDIR "G:\DFSR"
IF NOT EXIST "G:\DFSR\Staging" MKDIR "G:\DFSR\Staging"
IF NOT EXIST "G:\DFSR\Staging\CertData" MKDIR "G:\DFSR\Staging\CertData"
Powershell -ExecutionPolicy bypass -file ".\Change-DFSRStaging.ps1"
IF EXIST "F:\inetpub\wwwroot\certdata\dfsrPrivate\staging" RMDIR /s /q "F:\inetpub\wwwroot\certdata\dfsrPrivate\staging"

File 2 – Change-DFSRStaging.ps1

Here’s a previous blog post of mine with very similar information: Changing the DSFR Staging Path with PowerShell.

#I want to change the stagingPath parameter of the respective instance of the DfsrReplicatedFolderConfig class
#The staging path is actually stored in AD
$computer = gc env:computername
$targetStagingPath = "G:\dfsr\staging\certdata"

#find the repl folder GUID
$ReplFolderConfigs = $null
$i = 0
While($ReplFolderConfigs -eq $null)
	{
		If($i -gt 0)
			{Sleep -seconds 2}
		ElseIf($i -gt 15)
			{
				$foundFolderConfigs = $false
				Break
			}
		$ReplFolderConfigs = gwmi -namespace "root\MicrosoftDFS" -class DfsrReplicatedFolderConfig
		$i++
	}

If(($ReplFolderConfigs.GetType().BaseType.Name) -eq "Array")
	{
		$ReplFolderConfigs | % {
			write-host -f cyan $_.RootPath
			If($_.RootPath -like "*inetPub*CertData*" -and $_.StagingPath -like "*inetPub*CertData*")
				{$replFolder = $_}
		}
	}
Else
	{$replFolder = $ReplFolderConfigs}
$folderGUID = $ReplFolder.ReplicatedFolderGuid

write-host -f cyan "folderGuid: $folderGUID"

#grab the objet from AD
$strFilter = "(&(objectClass=msDFSR-Subscription)(CN=" + $folderGUID + "))"
$objDomain = New-Object System.DirectoryServices.DirectoryEntry
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.Filter = $strFilter
$colResults = $objSearcher.FindAll()

If(($colResults.PSBase.GetType().Name) -eq "SearchResult")
	{$sDFSRConfigLDAPPath = $colResults.Path}
Else
	{
		$colResults | % {
			$result = $_
			$ldapResult = $result.Path
#			write-host -f green $ldapResult
			If($ldapResult -like ("*" + $computer + "*"))
				{$sDFSRConfigLDAPPath = $ldapResult}
		}
	}

#write-host -f yellow "sDFSRConfigLDAPPath: $sDFSRConfigLDAPPath"
$objDFSRConfig = [adsi]$sDFSRConfigLDAPPath

#modify the property
$stagepath = $objDFSRConfig.Get("msDFSR-StagingPath")
#write-host -f yellow "Current staging path: $stagepath"
$objDFSRConfig.Put("msDFSR-StagingPath",$targetStagingPath)
$objDFSRConfig.SetInfo()

#restart the dfsr service
Restart-Service DFSR
Sleep -seconds 10

Running the install-dfsr.cmd script on both Sub CA’s should start them sync’ing their inetpub folders! Stay tuned for Part 4.

Changing the DSFR Staging Path with PowerShell

It took a while to figure out, but it’s totally possible to change the DFSR Staging Path programatically for any replicated folder. Here’s the scoop!

Required Reading

The Script

You’ll need to change the variables at the top.

#I want to change the stagingPath parameter of the respective instance of the DfsrReplicatedFolderConfig class
#The staging path is actually stored in AD
$computer = gc env:computername
$targetStagingPath = "G:\dfsr\staging\certdata"
$rootPathToLookFor = "*inetPub*CertData*"

#find the repl folder GUID
$ReplFolderConfigs = $null
$i = 0
While($ReplFolderConfigs -eq $null)
	{
		If($i -gt 0)
			{Sleep -seconds 2}
		ElseIf($i -gt 15)
			{
				$foundFolderConfigs = $false
				Break
			}
		$ReplFolderConfigs = gwmi -namespace "root\MicrosoftDFS" -class DfsrReplicatedFolderConfig
		$i++
	}

If(($ReplFolderConfigs.GetType().BaseType.Name) -eq "Array")
	{
		$ReplFolderConfigs | % {
			write-host -f cyan $_.RootPath
			If($_.RootPath -like $rootPathToLookFor -and $_.StagingPath -like $rootPathToLookFor)
				{$replFolder = $_}
		}
	}
Else
	{$replFolder = $ReplFolderConfigs}
$folderGUID = $ReplFolder.ReplicatedFolderGuid

write-host -f cyan "folderGuid: $folderGUID"

#grab the objet from AD
$strFilter = "(&(objectClass=msDFSR-Subscription)(CN=" + $folderGUID + "))"
$objDomain = New-Object System.DirectoryServices.DirectoryEntry
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.Filter = $strFilter
$colResults = $objSearcher.FindAll()

If(($colResults.PSBase.GetType().Name) -eq "SearchResult")
	{$sDFSRConfigLDAPPath = $colResults.Path}
Else
	{
		$colResults | % {
			$result = $_
			$ldapResult = $result.Path
#			write-host -f green $ldapResult
			If($ldapResult -like ("*" + $computer + "*"))
				{$sDFSRConfigLDAPPath = $ldapResult}
		}
	}

#write-host -f yellow "sDFSRConfigLDAPPath: $sDFSRConfigLDAPPath"
$objDFSRConfig = [adsi]$sDFSRConfigLDAPPath

#modify the property
$stagepath = $objDFSRConfig.Get("msDFSR-StagingPath")
#write-host -f yellow "Current staging path: $stagepath"
$objDFSRConfig.Put("msDFSR-StagingPath",$targetStagingPath)
$objDFSRConfig.SetInfo()

#restart the dfsr service
Restart-Service DFSR
Sleep -seconds 10

Thanks for reading!

Load Balancing IIS with NLB and DFS

I’m in the middle of a PKI (ADCS) project, and realized that I need a reliable web server. Here’s what I found out about clustering IIS.

Quick Notes

  • MSCS works with IIS in active\passive mode. However, NLB is active\active.
  • NLB is a port-level clustering solution and is not aware of CPU\RAM load or application health. If the networking stack is up then the server gets traffic.
  • NLB is a mesh topology and doesn’t use a dispatcher.
  • NLB doesn’t replicate content. DFS can though!

How It Works

In a NLB cluster, all members share the same MAC and IP Address. This means that all hosts receive incoming traffic for the cluster’s IP address (called the VIP or Virtual IP Address). NLB is actually first and foremost a driver which sits on the TCP stack and selectively filters out packets so that the hosts ignore traffic not assigned to them. The hosts communicate with each other and elect which members will handle incoming requests and sessions via broadcasts to the cluster’s MAC address. This broadcast can either be a unicast (broadcast to the entire subnet), or IGMP Multicast (broadcast only to ports with other cluster members). If you’re using VMWare, and in most other situations, IGMP Multicast is the way to go.

Setting Up a Cluster – Server 1

  1. Rename the interface you’re using for NLB traffic from “Local Area Network #” to “NLB Interface”.
  2. Install IIS
    Dos command:

    Powershell -executionpolicy bypass -command "Import-Module ServerManager; Add-WindowsFeature net-framework-core"
    PKGMGR.EXE /l:log.etw /iu:IIS-WebServerRole;IIS-WebServer;IIS-CommonHttpFeatures;IIS-StaticContent;IIS-DefaultDocument;IIS-HttpErrors;IIS-HttpRedirect;IIS-ApplicationDevelopment;IIS-ASP;IIS-ISAPIExtensions;IIS-HealthAndDiagnostics;IIS-HttpLogging;IIS-LoggingLibraries;IIS-RequestMonitor;IIS-HttpTracing;IIS-Security;IIS-WindowsAuthentication;IIS-RequestFiltering;IIS-IPSecurity;IIS-Performance;IIS-HttpCompressionStatic;IIS-WebServerManagementTools;IIS-IIS6ManagementCompatibility;IIS-Metabase
  3. Install the NLB feature
    Dos command:

    Ocsetup.exe NetworkLoadBalancingFullServer
  4. Create the cluster
    Powershell Commands:

    Import-Module NetworkLoadBalancingClusters
    New-NlbCluster -ClusterName "Cluster1" -ClusterPrimaryIP <VIP> -SubnetMask <VIPSubnetMask> -OperationMode "igmpmulticast" -interfaceName "NLB Interface" -force
  5. Set port rules for port 80
    Powershell Commands:

    Get-NLBClusterPortRule | Remove-NlbClusterPortRule -Force
    Add-NlbClusterPortRule -mode multiple -affinity single -startport 80 -endport 80 -protocol tcp -interfaceName "NLB Interface"
  6. Disable unneeded protocols, Set the DNS, gateway, and interface metrics
    Dos commands:

    nvspbind.exe /d "NLB Interface" ms_tcpip6
    nvspbind.exe /d "NLB Interface" ms_netbt
    nvspbind.exe /d "NLB Interface" ms_smb
    nvspbind.exe /d "NLB Interface" ms_lltdio
    nvspbind.exe /d "NLB Interface" ms_rspndr
    nvspbind.exe /d "NLB Interface" ms_pppoe
    
    netsh interface ipv4 add dnsserver name="NLB Interface" address=xxx.xxx.xxx.xxx index=1
    netsh interface ipv4 add dnsserver name="NLB Interface" address=xxx.xxx.xxx.xxx index=2
    netsh interface ipv4 add address "NLB Interface" gateway=xxx.xxx.xxx.xxx gwmetric=2
    netsh interface ipv4 set interface "NLB Interface" metric=2
    netsh interface ipv4 set interface "eth0, LAN Network" metric=1
  7. Install DFSR and Create a DFSR Replication Group, then add the current system’s wwwroot as a replicated folder.
    Dos Commands

    Powershell -executionpolicy bypass -command "Import-Module ServerManager; Add-WindowsFeature File-Services,FS-DFS,FS-DFS-Replication"
    dfsradmin RG New /rgname:"Cluster1 Replication Group"
    dfsrAdmin RG Set Schedule full /RGName:"Cluster1 Replication Group"
    dfsradmin member new /rgname:"Cluster1 Replication Group" /memname:%computername%
    dfsradmin RF New /rgName:"Cluster1 Replication Group" /RfName:wwwRoot
    dfsradmin Membership Set /RgName:"Cluster1 Replication Group" /RfName:wwwRoot /MemName:%computername% /LocalPath:C:\inetpub\wwwroot /MembershipEnabled:true /IsPrimary:true

Server 2

  1. Install IIS (same as above)
  2. Install the NLB feature (same as above)
  3. Add the host to the cluster
    Powershell Commands:

    #Add host
    (Get-NLBCluster -hostname nlb1.domain.com) | Where-Object {$_.Name -eq "Cluster1"} | `
    	Add-NLBClusterNode -NewNodeName "nlb2" -newNodeInterface "NLB Interface" -force
    
    #remove default Dedicated IP
    (Get-NlbClusterNodeDip -nodename nlb2) | Remove-NlbClusterNodeDip -force
  4. Set the gateway and interface metrics (same as above)
  5. Add the host to the DFS Replication Group, add inetPub as replicated folder, and add connections between the hosts.
    Dos Commands:

    Powershell -executionpolicy bypass -command "Import-Module ServerManager; Add-WindowsFeature File-Services,FS-DFS,FS-DFS-Replication"
    dfsradmin member new /rgname:"Cluster1 Replication Group" /memname:%computername%
    dfsradmin Membership Set /RgName:"Cluster1 Replication Group" /RfName:wwwRoot /MemName:%computername% /LocalPath:C:\inetpub\wwwroot /MembershipEnabled:true /IsPrimary:false
    
    dfsradmin conn new /rgname:"Cluster1 Replication Group" /SendMem:nlb1 /RecvMem:%computername% /ConnEnabled:true
    dfsradmin conn new /rgname:"Cluster1 Replication Group" /SendMem:%computername% /RecvMem:nlb1 /ConnEnabled:true

Testing

Open the Network Load Balancing GUI from Administrative Tools and stop both hosts. Opening your VIP in internet explorer should fail. Next, try enabling each host separately and visiting the VIP. The VIP should work after each test once convergence takes place.

Once again, have fun doing good things. JP