Iis – Creating a web farm in PowerShell

arriisload balancingpowershell

I'm trying to automate the creation of a server farm in PowerShell. Through manual creation I've got the following XML:

<webFarms>
    <webFarm name="alwaysup" enabled="true">
        <server address="alwaysup-blue" enabled="true">
            <applicationRequestRouting httpPort="8001" />
        </server>
        <server address="alwaysup-green" enabled="true">
            <applicationRequestRouting httpPort="8002" />
        </server>
        <applicationRequestRouting>
            <healthCheck url="http://alwaysup/up.html" interval="00:00:05" responseMatch="up" />
        </applicationRequestRouting>
    </webFarm>
    <applicationRequestRouting>
        <hostAffinityProviderList>
            <add name="Microsoft.Web.Arr.HostNameRoundRobin" />
        </hostAffinityProviderList>
    </applicationRequestRouting>
</webFarms>

Trying to do this via PS proves troublesome however: as far as I can tell there is no dedicated API to do this through (WebFarmSnapin is meant for an older version).

I have shifted my attention to IIS Administration Cmdlets but only got it half working.

The code that I have:

#####
# Overwriting the server farm
#####

Write-Host "Overwriting the server farm $($webFarmName)"

$webFarm = @{};
$webFarm["name"] = 'siteFarm'

Set-WebConfiguration "/webFarms" -Value $webFarm

#####
# Adding the servers
#####

Write-Host "Adding the servers"

$blueServer = @{}
$blueServer["address"] = 'site-blue'
$blueServer["applicationRequestRouting"] = @{}

$greenServer = @{}
$greenServer["address"] = 'site-green'
$greenServer["applicationRequestRouting"] = @{}

$servers = @($blueServer, $greenServer)

Add-WebConfiguration -Filter "/webFarms/webFarm[@name='siteFarm']" -Value $servers

#####
# Adding routing
#####

Write-Host "Adding the routing configurations"

$blueServerRouting = @{}
$blueServerRouting["httpPort"] = "8001"
Add-WebConfiguration -Filter "/webFarms/webFarm[@name='siteFarm']/server[@address='site-blue']" -Value $blueServerRouting

This generates

<webFarms>
    <webFarm name="siteFarm">
        <server address="site-blue" />
        <server address="site-green" />
    </webFarm>
    <applicationRequestRouting>
        <hostAffinityProviderList>
            <add name="Microsoft.Web.Arr.HostNameRoundRobin" />
        </hostAffinityProviderList>
    </applicationRequestRouting>
</webFarms>

As you can see it's missing the port related to the routing. And I haven't even started with trying to add the healthcheck at this point.

What am I doing wrong? Is there some Cmdlet that I haven't found which makes this easier?

Related but without much of a useful answer (the PowerShell tab with generated code stays empty).

Crossposted it here from SO after realizing SF exists and might be more appropriate.

Best Answer

The best way I've seen to accomplish this is by mixing powershell with the appcmd.exe command. Microsoft has released some sample code for setting up a farm in a docker container here.

Here's an example:

ForEach($farm in $farms)
{   
    # Create the farm
    .\appcmd.exe set config  -section:webFarms /+"[name='$($farm.name)']" /commit:apphost

    ForEach($server in $farm.Servers)
    {
        # Add server to farm
        .\appcmd.exe set config  -section:webFarms /+"[name='$($farm.name)'].[address='$($server.address)']" /commit:apphost
    }

    # URL Rewrite
    .\appcmd.exe set config  -section:system.webServer/rewrite/globalRules /+"[name='ARR_$($farm.name)_lb', patternSyntax='Wildcard',stopProcessing='True']" /commit:apphost
    .\appcmd.exe set config  -section:system.webServer/rewrite/globalRules /"[name='ARR_$($farm.name)_lb',patternSyntax='Wildcard',stopProcessing='True']".match.url:"*"  /commit:apphost
    .\appcmd.exe set config  -section:system.webServer/rewrite/globalRules /"[name='ARR_$($farm.name)_lb',patternSyntax='Wildcard',stopProcessing='True']".action.type:"Rewrite"  /"[name='ARR_$($farm.name)_lb',patternSyntax='Wildcard',stopProcessing='True']".action.url:"http://$($farm.name)/{R:0}"  /commit:apphost
}