我正在尝试在PowerShell中自动创建服务器场。通过手动创建,我得到了以下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>

但是,尝试通过PS进行操作却很麻烦:据我所知,没有专用的API可以通过这样做(WebFarmSnapin是针对较旧的版本的)。

我将注意力转移到了IIS Administration Cmdlets上,但只成功了一半。

我拥有的代码:
#####
# 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

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

如您所见,它缺少与路由相关的端口。现在,我甚至还没有开始尝试添加运行状况检查。

我究竟做错了什么?是否有一些我没有找到的Cmdlet使得它更容易?

Related,但没有很多有用的答案(带有生成代码的PowerShell选项卡保持为空)。

最佳答案

您似乎已经找到了如何通过修改XML配置文件本身来执行此操作。尽管感觉这似乎不是“正确的方法”,但是直接更改配置文件是一个非常有效的解决方案。本质上,您创建了一个模板,配置模板为生成可维护和可重复的配置提供了一种快速且易读的方法。

我们可以通过从脚本中提取模板文本到单独的文本文件中来改进这种方法。然后,脚本可以读取(或获取)模板,并根据需要交换出所有占位符值。这类似于我们通过将HTML模板与代码分离来在Web应用程序中分离关注点的方式。

为了更直接地回答这个问题,让我们看一下如何使用PowerShell和IIS管理API来执行此操作(您是正确的-如果IIS和Windows,则新版本不再支持Web Farm Framework)。问题中的原始代码是一个好的开始。我们只需要区分操作配置集合(使用*-WebConfiguration cmdlet)和配置项(使用*-WebConfigurationProperty cmdlet)。这是一个脚本,它将根据问题中的示例设置配置值:

$farmName = 'siteFarm'

Add-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' `
    -Filter 'webFarms' `
    -Name '.'  `
    -Value @{ name = $farmName; enabled = $true }

Add-WebConfiguration -PSPath 'MACHINE/WEBROOT/APPHOST' `
    -Filter "webFarms/webFarm[@name='$farmName']" `
    -Value @(
        @{ address = 'site-blue'; enabled = $true },
        @{ address = 'site-green'; enabled = $true }
    )

Set-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' `
    -Filter "webFarms/webFarm[@name='$farmName']/server[@address='site-blue']" `
    -Name 'applicationRequestRouting' `
    -Value @{ httpPort = 8001 }

Set-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' `
    -Filter "webFarms/webFarm[@name='$farmName']/server[@address='site-green']" `
    -Name 'applicationRequestRouting' `
    -Value @{ httpPort = 8002 }

Set-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' `
    -Filter "webFarms/webFarm[@name='$farmName']/applicationRequestRouting" `
    -Name 'healthCheck' `
    -Value @{
        url = 'http://mySite/up.html'
        interval = '00:00:05'
        responseMatch = 'up'
    }

Set-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' `
    -Filter "webFarms/webFarm[@name='$farmName']/applicationRequestRouting" `
    -Name 'protocol' `
    -Value @{ reverseRewriteHostInResponseHeaders = $true }

Set-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' `
    -Filter "webFarms/webFarm[@name='$farmName']/applicationRequestRouting/protocol" `
    -Name 'cache' `
    -Value @{ enabled = $false; queryStringHandling = 'NoCaching' }

这可能比必要时更冗长,但是我想清楚地说明每个步骤中的意图。此实现将XPath查询用于-Filter参数,以选择适当的XML节点。我们也许可以重构脚本以减少重复的任务,例如通过定义一个Add-FarmServer函数,该函数使用服务器名称和端口,然后添加适当的指令。如果遇到锁定的配置问题,我们可能还需要 Remove-WebConfigurationLock

我们选择使用模板还是编程方式取决于项目和团队的偏好。当我们要配置许多类似项时(例如,如果要向Web场添加数百台服务器),API将变得更具吸引力。另一方面,模板易于理解,不需要其他团队成员学习新的(也许有些令人困惑)API。

09-27 02:09
查看更多