[英]Creating a web farm in PowerShell
我正在嘗試在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管理Cmdlet,但只有一半工作。
我的代碼:
#####
# 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使這更容易?
相關但沒有太多有用的答案(生成的代碼的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' }
這可能比必要的更冗長,但我想清楚地說明每一步的意圖。 此實現對-Filter
參數使用XPath查詢來選擇適當的XML節點。 或許,我們可以重構腳本以減少重復性任務,例如通過定義一個帶有服務器名稱和端口的Add-FarmServer
函數,然后添加適當的指令。 如果遇到鎖定的配置問題,我們可能還需要Remove-WebConfigurationLock
。
我們選擇使用模板還是程序化方法取決於項目和團隊偏好。 當我們要配置許多類似的項目時,API變得更有吸引力,例如,如果我們有數百台服務器要添加到Web場。 另一方面,模板易於理解,不要求其他團隊成員學習新的(可能有些令人困惑的)API。
我一直在努力,我發現你可以在Powershell中使用Microsoft.Web.Administration
來實現這一目標。
Add-Type -AssemblyName "Microsoft.Web.Administration, Version=7.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"
$iisManager = New-Object Microsoft.Web.Administration.ServerManager
$applicationHostConfig = $IISManager.GetApplicationHostConfiguration()
# Get the WebFarms section. Section names are case-sensitive.
$webFarmSection = $ApplicationHostConfig.GetSection("webFarms")
$webFarms = $WebFarmSection.GetCollection()
# Create a new webfarm and assign a name.
$webFarm = $WebFarms.CreateElement("webFarm")
$webFarm.SetAttributeValue("name", "MyNewWebFarmName")
# Add it to the parent element
$webFarms.Add($webFarm)
# get Webfarm server collection
$servers = $webFarm.GetCollection()
# add server
$serverBlue = $servers.CreateElement("server")
$routingBlue = $serverBlue.GetChildElement("applicationRequestRouting")
$routingBlue.SetAttributeValue("httpPort", "8001")
$serverBlue.SetAttributeValue("address", "MyNewWebFarmName-blue")
$servers.Add($serverBlue)
# Save changes
$iisManager.CommitChanges()
有兩件事值得一提:
一旦調用$iisManager.CommitChanges()
,對象就會進入只讀模式。 在進行任何新更改之前,您需要重新實例化所有對象。
如果您決定在Web場中創建新服務器,則在為服務器分配名稱然后嘗試訪問其端口設置時,您將遇到問題。 您需要做的是先分配端口,然后分配名稱以及是否啟用/禁用。 否則,它將拋出System.AccessViolationException: Attempted to read or write protected memory.
錯誤。
讓我知道事情的后續!
看上去沒有人提出解決方案:我采用了非常簡單的解決方法,即直接編輯XML而不是通過API。
實際的webfarm功能我還沒有工作,但似乎所有的部分至少存在。
操作XML的一個例子是:
$configPath = "C:\Windows\System32\inetsrv\config\applicationHost.config"
$configXml = [xml] (type $configPath)
[xml] $webFarmXml = @"
<webFarms>
<webFarm name="siteFarm" enabled="true">
<server address="site-blue" enabled="true">
<applicationRequestRouting httpPort="$bluePort" />
</server>
<server address="site-green" enabled="true">
<applicationRequestRouting httpPort="$greenPort" />
</server>
<applicationRequestRouting>
<healthCheck url="http://mySite/up.html" interval="00:00:05" responseMatch="up" />
<protocol reverseRewriteHostInResponseHeaders="true">
<cache enabled="false" queryStringHandling="NoCaching" />
</protocol>
</applicationRequestRouting>
</webFarm>
<applicationRequestRouting>
<hostAffinityProviderList>
<add name="Microsoft.Web.Arr.HostNameRoundRobin" />
</hostAffinityProviderList>
</applicationRequestRouting>
</webFarms>
"@
$configXml.configuration.AppendChild($configXml.ImportNode($webFarmXml.webFarms, $true))
$configXml.Save($configPath)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.