2017-11-09 9 views
14

Ich versuche, die Erstellung einer Serverfarm in PowerShell zu automatisieren. Durch manuelle Erstellung habe ich die folgende XML bekam:Erstellen einer Webfarm in PowerShell

<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> 

Der Versuch, dies über PS zu tun aber lästig erweist: soweit ich keine dedizierte es sagen kann API ist, dies zu tun durch (WebFarmSnapin ist für eine ältere gemeint Ausführung).

Ich habe meine Aufmerksamkeit auf IIS Administration Cmdlets verlagert, aber es hat nur halb funktioniert.

Der Code, den ich habe:

##### 
# 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 

Dies erzeugt

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

Wie Sie es fehlt den Hafen im Zusammenhang mit dem Routing sehen. Und ich habe noch nicht einmal damit begonnen, den Gesundheitscheck an dieser Stelle hinzuzufügen.

Was mache ich falsch? Gibt es ein Cmdlet, das ich nicht gefunden habe, was das einfacher macht?

Related aber ohne viel nützliche Antwort (die Registerkarte PowerShell mit generiertem Code bleibt leer).

+0

Sie könnten versuchen und sehen, ob der IIS-Anbieter tun kann, was Sie wollen https://technet.microsoft.com/en-us/library/ee909471(v=ws.10).aspx Es ist wohl ein bisschen mehr nitty -gritty als mit IIS-Cmdlets, aber manchmal ist es das, was es braucht. – mtnielsen

+0

Haben Sie sich dieses Cmdlet angesehen, um den Port zu konfigurieren? 'Set-WebBinding -Name 'Standard-Website' -BindingInformation '*: 80:" -PropertyName "Port" -Value "1234" 'Ich kenne Webfarms nicht genug, um zu wissen, ob Ihnen das hilft oder nicht. – FoxDeploy

+0

Wenn Sie dies noch nicht getan haben, würde ich vorschlagen, in die [xWebAdministration DSC-Ressource] (https://github.com/PowerShell/xWebAdministration) zu schauen, um die Erstellung/Konfiguration/den gewünschten Status der Webfarm zu automatisieren. Das WebAdministration-Modul lässt viel zu wünschen übrig (sprechen von Erfahrung nach der Automatisierung einiger IIS-Setup früher in diesem Jahr) – TheIncorrigible1

Antwort

3

Es sieht aus wie Sie herausgefunden, wie dies die XML-Konfigurationsdatei selbst durch Modifizieren zu tun. Trotz des Gefühls, dass dies nicht ganz nach dem "richtigen Weg" aussieht, ist eine Änderung der Konfigurationsdatei eine vollkommen gültige Lösung. Im Wesentlichen haben Sie eine Vorlage erstellt, und Konfigurationsvorlagen bieten einen schnellen und lesbaren Ansatz zum Erstellen wartbarer und wiederholbarer Konfigurationen.

Wir können diesen Ansatz verbessern, indem wir den Schablonentext aus dem Skript in eine separate Textdatei extrahieren. Anschließend können Skripts die Vorlage lesen (oder Quelle) und beliebige Platzhalterwerte nach Bedarf austauschen. Dies ist vergleichbar mit dem Trennen von Problemen in einer Webanwendung durch Entkoppeln unserer HTML-Vorlagen vom Code.

Um die Frage direkter zu beantworten, werfen wir einen Blick auf die Verwendung von PowerShell und der IIS-Verwaltungs-API (Sie sind korrekt — Webfarm-Framework wird nicht mehr für aktuelle Versionen unterstützt, wenn IIS und Windows). Der ursprüngliche Code in der Frage ist ein guter Anfang. Wir müssen lediglich zwischen der Manipulation der Konfiguration Sammlungen (mit *-WebConfiguration cmdlets) und der Konfiguration Elemente (mit *-WebConfigurationProperty cmdlets) unterscheiden. Hier ist ein Skript, das die Konfigurationswerte basierend auf dem Beispiel in der Frage festgelegt werden:

$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' } 

Dies kann etwas ausführlicher als notwendig sein, aber ich wollte eindeutig die Absicht, in jedem Schritt erläutern.Diese Implementierung verwendet XPath-Abfragen für die Argumente -Filter, um die entsprechenden XML-Knoten auszuwählen. Wir könnten das Skript möglicherweise reformieren, um sich wiederholende Aufgaben zu reduzieren, indem wir beispielsweise eine Add-FarmServer-Funktion definieren, die einen Servernamen und einen Port annimmt und dann die entsprechenden Anweisungen hinzufügt. Wir können auch Remove-WebConfigurationLock benötigen, wenn wir auf gesperrte Konfigurationsprobleme stoßen.

Ob wir eine Vorlage oder einen programmatischen Ansatz verwenden, hängt von den Projekt- und Teameinstellungen ab. Die API wird viel attraktiver, wenn wir viele ähnliche Elemente konfigurieren müssen, z. B. wenn wir Hunderte von Servern zu einer Webfarm hinzufügen müssen. Auf der anderen Seite, Vorlagen sind einfach zu verstehen, erfordern nicht, dass andere Teammitglieder eine neue (und vielleicht etwas verwirrend) API lernen.

+1

Vielen Dank für die aufschlussreiche Antwort! Ich mochte meinen Ansatz nicht ganz, da er nur einen kleinen Teil von XML hinzufügt, sodass ich Ihren mag, da er zumindest die XML-APIs verwendet, um ihn zu manipulieren. –

1

Da niemand eine Lösung gefunden hat: Ich habe die sehr einfache Problemumgehung des direkten Editierens der XML-Datei genommen, anstatt über eine API zu gehen.

Die eigentliche Webfarm-Funktionalität muss ich noch nicht arbeiten, aber es scheint, als ob alle Teile mindestens da sind.

Ein Beispiel für die XML-Manipulation das sein kann:

$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) 
+0

Warum hast du dieses 'xml' nicht direkt mit dem PowerShell-Skript erstellt? –

1

Ich habe daran gearbeitet und ich habe festgestellt, dass Sie in Powershell verwenden können, um dies zu erreichen.

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) 
# Save changes 
$iisManager.CommitChanges() 

Es gibt zwei Dinge, die wichtig zu erwähnen sind:

  1. Sobald Sie rufen $iisManager.CommitChanges() dann das Objekt in Nur-Lese-Modus geht. Sie müssen alle Objekte erneut instanziieren, bevor Sie neue Änderungen vornehmen.

  2. Wenn Sie einen neuen Server in Ihrer Webfarm erstellen, tritt ein Problem auf, wenn Sie dem Server einen Namen zuweisen und dann versuchen, auf seine Porteinstellungen zuzugreifen. Was Sie tun müssen, ist, den Port zuerst zuzuweisen und dann den Namen zuzuweisen und ob er aktiviert/deaktiviert ist. Andernfalls wird ein Fehler System.AccessViolationException: Attempted to read or write protected memory. ausgelöst.

Lassen Sie mich wissen, wie es geht!

Verwandte Themen