Skip to main content
İkinci Bir Web Siteleri Denetleyicisi Sağlama
 

Uygulama Alanı: Windows Azure Pack

Microsoft Azure Pack: Web Siteleri en fazla iki Web Siteleri Denetleyiciye sahip olabilir. Yüksek Kullanılabilirlik için bu üst sınırı uygulamanız ve ikinci bir Web Siteleri Denetleyici sağlamanız önerilir. Bunu yapmak için burada verilen aşağıdaki betikler kullanılabilir:

OnStartSecondaryController.cmd

HostingBootstrapperBootstrapper.ps1

OnStartSecondaryController.ps1

Common.ps1

  • OnStartSecondaryController.cmd - Web Platformu Yükleyicisi'ni (Web PI) Windows 2012 sunucusuna veya hazırladığınız Sanal Makineye yükler. Daha sonra ikincil denetleyicinin sağlamasını tamamlamak için HostingBootstrapperBootstrapper ve OnStartSecondaryController betiklerini art arda çağırır. Gerekli parametreler, kurulumda kullanılacak olan SQL Server ve Denetleyici yönetici kimlik bilgilerini içerir.

  • HostingBootstrapperBootstrapper.ps1 - İkinci Web Siteleri Denetleyiciyi yüklemek için Program Files\Microsoft\Web Platform Installer\WebpiCmd.exe dosyasını çağırır. Birincil denetleyiciyi yüklerken kullanılan yordamın aynısını kullanır, ancak /SuppressPostFinish komut satırı anahtarını belirterek yapılandırma portalını iptal eder.

  • OnStartSecondaryController.ps1 - SystemCore ve SiteRuntime anahtarları ve barındırma ve kaynak ölçümü bağlantı dizeleri dahil olmak üzere yapılandırma verilerini birincil denetleyiciden ikincil denetleyiciye kopyalar. Tamamlandığında, WebFarmService'i başlatır.

  • Common.ps1 - OnStartSecondaryController.ps1 betiği için destekleyici işlevler sağlar.

System_CAPS_importantÖnemli

Bu betikler, Windows Uzaktan Yönetim'in (WinRM) birincil denetleyicide etkinleştirilmesini gerektirir.

  1. Betikleri İkincil Denetleyici olacak sunucuda bir klasöre kopyalayın.

  2. WebPlatformInstaller.msi dosyasını betiklerle aynı klasöre kopyalayın. OnStartSecondaryController.cmd betiği Web PI yüklemesini otomatikleştirdiğinden bunun yapılması gereklidir.

  3. OnStartSecondaryController.cmd betiğini yönetici haklarıyla çalıştırın ve aşağıdaki tabloda açıklanan parametreleri belirtin. Yönetici ayrıcalıkları, uygun ürünlerin Web PI otomasyonu yoluyla yüklenebilmesi ve birincil denetleyiciye WinRM üzerinden erişilebilmesi için gereklidir.

    System_CAPS_noteNot

    Bir WORKGROUP senaryosunda birincil denetleyicide WinRM'yi etkinleştirmeniz veya OnStartSecondaryController.cmd betiğindeki komutları elle çalıştırmanız gerekebilir.

OnStartSecondaryController.cmd -feed %Feed% -webSitesInstanceName %WebSitesInstanceName% -sqlservername %DatabaseServerName% -sqlsysadmin %DatabaseSysAdminAccount% -sqlsysadminpwd %DatabaseSysAdminPassword% -controllerAdminUserName %ControllerAdminUserName% -controllerAdminPassword %ControllerAdminPassword%

Parametre Adı

Açıklama

Notlar

feed

Denetleyiciyi yüklemek için kullanılacak Web PI akışını isteğe bağlı olarak belirtir.

Bu parametre belirtilmemişse, varsayılan Web PI birincil akışı kullanılır.

webSitesInstanceName

Veritabanı nesneleri için önek olarak kullanılır

Yüklemede veritabanının önek adı ile eşleşmelidir.

sqlservername

SQL server örneğinin adı

sqlsysadmin

SQL Server sistem yönetici kullanıcı hesabının adı

Sysadmin sunucu rollerinin üyesi olmalıdır.

sqlsysadminpwd

SQL Server sistem yöneticisi kullanıcı hesabı parolası

controllerAdminUserName

Sağlanacak Web Grubu Çerçevesi (WFF) Yönetici hesap adı

Bu bir etki alanı hesabıysa, local administrators grubuna eklenir.

Sunucu bir WORKGROUP içindeyse, kullanıcının mevcut olmaması durumunda kullanıcıyı oluşturmaya ve local administrators grubuna eklemeye çalışır.

controllerAdminPassword

Sağlanacak WFF Yönetici hesap parolası

@echo off
echo Starting OnStartSecondaryController.cmd

rem ---------------------------------------------
rem Initialize Variables
rem ---------------------------------------------
    set POWERSHELL=%windir%\System32\WindowsPowerShell\v1.0\powershell.exe

    set FEED=
    set INSTANCE_NAME=
    set SQL_SERVERNAME=
    set SQL_SYSADMIN=
    set SQL_SYSADMINPWD=
    set CONTROLLER_ADMIN_USERNAME=
    set CONTROLLER_ADMIN_PASSWORD=

rem ---------------------------------------------
rem Parse command line parameters
rem ---------------------------------------------
:parse_param
    set PARAM_MATCHED=0
    if "%1"=="" (
        goto :parse_param_completed
    )

    if /I "%1"=="-feed" (
        set FEED=%2
        shift
        set PARAM_MATCHED=1
    )

    if /I "%1"=="-webSitesInstanceName" (
        set INSTANCE_NAME=%2
        shift
        set PARAM_MATCHED=1
    )

    if /I "%1"=="-sqlservername" (
        set SQL_SERVERNAME=%2
        shift
        set PARAM_MATCHED=1
    )

    if /I "%1"=="-sqlsysadmin" (
        set SQL_SYSADMIN=%2
        shift
        set PARAM_MATCHED=1
    )

    if /I "%1"=="-sqlsysadminpwd" (
        set SQL_SYSADMINPWD=%2
        shift
        set PARAM_MATCHED=1
    )

    if /I "%1"=="-controllerAdminUserName" (
        set CONTROLLER_ADMIN_USERNAME=%2
        shift
        set PARAM_MATCHED=1
    )

    if /I "%1"=="-controllerAdminPassword" (
        set CONTROLLER_ADMIN_PASSWORD=%2
        shift
        set PARAM_MATCHED=1
    )

    if "%PARAM_MATCHED%"=="0" (
       echo Parameter %1 was not matched
       exit 1
    )

    shift
    goto :parse_param
:parse_param_completed

rem -----------------------------------------------------------------------
rem Provision Controller
rem ------------------------------------------------------------------------

    echo Installing WebPlatformInstaller.
    start /wait %windir%\system32\msiexec.exe /qn /i WebPlatformInstaller.msi /l %SystemDrive%\WebPlatformInstaller.log
    if errorlevel 1 (
        echo WebPlatform Installer installation failed. See log at %SystemDrive%\WebPlatformInstaller.log for more details.
        exit 1
    )

    echo WebPlatformInstaller setup completed successfully.

    echo Enabling remote desktop access.
    start /wait cscript %windir%\system32\scregedit.wsf /ar 0
    if errorlevel 1 (
        echo Enabling remote desktop failed.
        exit 1
    )

    echo Remote desktop access has been enabled successfully.

    if exist StrongNameHijack.msi (

        echo Installing StrongNameHijack...
        start /wait %windir%\system32\msiexec.exe /qn /i StrongNameHijack.msi /l %SystemDrive%\StrongNameHijack.log
        if errorlevel 1 (
            echo "StrongNameHijack installation failed. See log at %SystemDrive%\StrongNameHijack.log for more details."
            exit 1
        )

        echo StrongNameHijack setup completed successfully.

        net stop msiserver & net start msiserver
    )

    echo Starting HostingBootstrapperBootstrapper.ps1

    if "%FEED%"=="" (
        %POWERSHELL% -ExecutionPolicy Unrestricted -File HostingBootstrapperBootstrapper.ps1
    ) else (
        %POWERSHELL% -ExecutionPolicy Unrestricted -File HostingBootstrapperBootstrapper.ps1 -mainFeed "%FEED%"
    )

    if errorlevel 1 (
        echo HostingBootstrapperBootstrapper.ps1 failed.
        exit 1
    )

    echo HostingBootstrapperBootstrapper.ps1 completed successfully.

    echo Starting OnStartSecondaryController.ps1

    %POWERSHELL% -ExecutionPolicy Unrestricted -File OnStartSecondaryController.ps1 -webSitesInstanceName "%INSTANCE_NAME%" -sqlservername "%SQL_SERVERNAME%" -sqlsysadmin "%SQL_SYSADMIN%" -sqlsysadminpwd "%SQL_SYSADMINPWD%" -controllerAdminUserName "%CONTROLLER_ADMIN_USERNAME%" -controllerAdminPassword "%CONTROLLER_ADMIN_PASSWORD%"
    if errorlevel 1 (
        echo OnStartSecondaryController.ps1 failed.
        exit 1
    )

    echo OnStartSecondaryController.ps1 completed successfully.

echo OnStartSecondaryController.cmd completed successfully.

exit 0
# PowerShell script to setup Web Sites Controller using WebPI.
# Copyright (c) Microsoft Corporation. All rights reserved.

Param
(
    [string] $boostrapperProductId = "HostingPrimaryControllerBootstrapper_v2",
    [string] $mainFeed = "",
    [string] $customFeed = ""
)

# Change Error Action to Stop
$ErrorActionPreference="Stop"

Function BootstrapBootstrapper ()
{
    $WebPiCmd = [System.Environment]::ExpandEnvironmentVariables("%ProgramW6432%\Microsoft\Web Platform Installer\WebpiCmd.exe")
    $WebPiLog = [System.Environment]::ExpandEnvironmentVariables("%SystemDrive%\HostingPrimaryControllerBootstrapper.log")

    If ($mainFeed -eq "")
    {
        Invoke-Command -ScriptBlock { & $WebPiCmd /Install /Products:$boostrapperProductId /AcceptEula /SuppressReboot /SuppressPostFinish /Log:$WebPiLog }
    }
    Else
    {
        If ($customFeed -eq "")
        {
            Invoke-Command -ScriptBlock { & $WebPiCmd /Install /Products:$boostrapperProductId /AcceptEula /SuppressReboot /SuppressPostFinish /XML:$mainFeed /Log:$WebPiLog }
        }
        Else
        {
            Invoke-Command -ScriptBlock { & $WebPiCmd /Install /Products:$boostrapperProductId /AcceptEula /SuppressReboot /SuppressPostFinish /XML:$mainFeed /Feeds:$customFeed /Log:$WebPiLog }
        }
    }

    If ($lastexitcode -ne $Null -And $lastexitcode -ne 0)
    {
        Exit $lastexitcode
    }
}

# Entry Point
BootstrapBootstrapper
# PowerShell script to setup a Web Sites secondary controller.
# Copyright (c) Microsoft Corporation. All rights reserved.

Param
(
    [string] $webSitesInstanceName,
    [string] $sqlservername,
    [string] $sqlsysadmin,
    [string] $sqlsysadminpwd,
    [string] $controllerAdminUserName,
    [string] $controllerAdminPassword
)

# Init Global Variables
$cnstr = "server=$($sqlservername);database=Hosting;uid=$($sqlsysadmin);pwd=$($sqlsysadminpwd);"

# Load common script file
$startDir = "."
$common = [System.IO.Path]::Combine($startDir, "Common.ps1")
. $common

Function Get-PrimaryController()
{
    Try
    {
        $siteManager = New-Object Microsoft.Web.Hosting.SiteManager $cnstr
        $primaryController = $siteManager.Controllers.GetPrimaryController([Microsoft.Web.Hosting.PlatformOptions]::VirtualMachineManager)

        Return $primaryController.MachineName;
    }
    Finally
    {
        If($siteManager -ne $Null)
        {
            $siteManager.Dispose()
        }
    }
}

Function Test-PrimaryController()
{
    Try
    {
        $PrimaryController = Get-PrimaryController

        Return $PrimaryController -ne $Null
    }
    Catch [Microsoft.Web.Hosting.WebHostingObjectNotFoundException]
    {
        Write-Host "$(Get-Date): Primary Controller NOT Ready"

        Return $False;
    }
}

Function WaitForPrimaryControllerToBeReady()
{
    $WaitIndex=0;
    $MaxWait=15
    $WaitInterval=60000

    Write-Host "$(Get-Date): Waiting for Primary Controller to be ready"

    $valid = Test-PrimaryController
    If ($valid -eq $False)
    {
        While ($WaitIndex -lt $MaxWait -and $valid -eq $False)
        {
            [System.Threading.Thread]::Sleep($WaitInterval);
            $WaitIndex = $WaitIndex + 1
            $valid = Test-PrimaryController
        }
    }

    If ($valid -eq $False)
    {
        Throw New-Object [System.Exception] "Primary Controller NOT ready. Timed out waiting."
    }

    Write-Host "$(Get-Date): Primary Controller is Ready"
}

Function Copy-SystemCoreKeyFromPrimaryController([string] $PrimaryController)
{
    Write-Host "$(Get-Date): Copy SystemCore key"

    $remoteCommand = {
        Add-PSSnapIn WebHostingSnapIn
        Get-WebSitesConfig -Type SecurityKey -SymmetricKeyName SystemCore
    }

    $SystemCoreKey = Invoke-Command -ComputerName $PrimaryController -ScriptBlock $remoteCommand
    Set-WebSitesConfig -Type SecurityKey -SymmetricKeyName SystemCore -SymmetricKey $SystemCoreKey -Force
}

Function Copy-SiteRuntimeKeyFromPrimaryController([string] $PrimaryController)
{
    Write-Host "$(Get-Date): Copy SiteRuntime key"

    $remoteCommand = {
        Add-PSSnapIn WebHostingSnapIn
        Get-WebSitesConfig -Type SecurityKey -SymmetricKeyName SiteRuntime
    }

    $SiteRuntimeKey  = Invoke-Command -ComputerName $PrimaryController -ScriptBlock $remoteCommand
    Set-WebSitesConfig -Type SecurityKey -SymmetricKeyName SiteRuntime -SymmetricKey $SiteRuntimeKey -Force
}

Function Copy-HostingConnectionStringFromPrimaryController([string] $PrimaryController)
{
    Write-Host "$(Get-Date): Copy hosting connection string"

    $remoteCommand = {
        Add-PSSnapIn WebHostingSnapIn
        [Microsoft.Web.Hosting.SiteManager]::GetDefaultConnectionString()
    }

    $HostingCnStr  = Invoke-Command -ComputerName $PrimaryController -ScriptBlock $remoteCommand
    Set-WebSitesConnectionString -Type Hosting -ConnectionString $HostingCnStr
}

Function Copy-MeteringConnectionStringFromPrimaryController([string] $PrimaryController)
{
    Write-Host "$(Get-Date): Copy metering connection string"

    $remoteCommand = {
        Add-PSSnapIn WebHostingSnapIn
        [Microsoft.Web.Hosting.SiteManager]::GetMeteringConnectionString()
    }

    $computerName = [Microsoft.Web.Hosting.Common.NetworkHelper]::GetComputerName([Microsoft.Web.Hosting.Common.ComputerNameFormat]::DnsFullyQualified)

    $MeteringCnStr  = Invoke-Command -ComputerName $PrimaryController -ScriptBlock $remoteCommand    
    Set-WebSitesConnectionString -Type Metering -ConnectionString $MeteringCnStr -ServerName $computerName
}

Function OnStartSecondaryController()
{
    Try
    {
        Write-Host "$(Get-Date): Starting OnStartSecondaryController()" -ForegroundColor Green

        Add-PSSnapin WebHostingSnapin

        ConfigureRoleAdministrator $controllerAdminUserName $controllerAdminPassword

        WaitForHostingDatabaseToBeReady $cnstr
        WaitForPrimaryControllerToBeReady

        $PrimaryController = Get-PrimaryController
        Copy-SystemCoreKeyFromPrimaryController $PrimaryController
        Copy-SiteRuntimeKeyFromPrimaryController $PrimaryController
        Copy-HostingConnectionStringFromPrimaryController $PrimaryController
        Copy-MeteringConnectionStringFromPrimaryController $PrimaryController

        Start-Service WebFarmService

        Write-Host "$(Get-Date): OnStartSecondaryController completed successfully" -ForegroundColor Green
    }
    Catch [System.Exception]
    {
        Write-Host "$(Get-Date): Exception encountered while executing OnStartSecondaryController:" -ForegroundColor Red
        Write-Host $_ -ForegroundColor Red

        Write-Host "$(Get-Date): Exiting OnStartSecondaryController.ps1" -ForegroundColor Red
        Exit -1
    }
}

# Entry Point
OnStartSecondaryController
# PowerShell Web Sites common script.
# Copyright (c) Microsoft Corporation. All rights reserved.

Function LoadHostingFramework()
{
    $mwhc = Get-Item ".\Microsoft.Web.Hosting.Common.dll"
    [void] [System.Reflection.Assembly]::LoadFrom($mwhc.FullName)
    Write-Host "$(Get-Date): Microsoft.Web.Hosting.Common assembly was successfully loaded from: $mwhc"

    $mwh  = Get-Item ".\Microsoft.Web.Hosting.dll"
    [void] [System.Reflection.Assembly]::LoadFrom($mwh.FullName)
    Write-Host "$(Get-Date): Microsoft.Web.Hosting assembly was successfully loaded from: $mwh"
}

Function IsHostingDatabaseReady([string] $cnstr)
{
    Try
    {
        $siteManager = New-Object Microsoft.Web.Hosting.SiteManager $cnstr
        $siteManager.TestConnection([Microsoft.Web.Hosting.PlatformOptions]::VirtualMachineManager)

        Return $true;
    }
    Catch [Exception]
    {
        Write-Host "$(Get-Date): Hosting Database NOT Ready"

        Return $false;
    }
    Finally
    {
        If($siteManager -ne $Null)
        {
            $siteManager.Dispose()
        }
    }
}

Function WaitForHostingDatabaseToBeReady ([string] $cnstr)
{
    $WaitIndex=0;
    $MaxWait=120
    $WaitInterval=60000

    Write-Host "$(Get-Date): Waiting for Hosting Database to be ready"

    $ready = IsHostingDatabaseReady $cnstr
    If($ready -ne $true)
    {
    While ($WaitIndex -lt $MaxWait -and $ready -ne $true)
        {
            [System.Threading.Thread]::Sleep($WaitInterval);
            $WaitIndex = $WaitIndex + 1
            $ready = IsHostingDatabaseReady $cnstr
        }
    }

    If ($ready -ne $true)
    {
        Throw New-Object [System.Exception] "Hosting Database NOT ready. Timed out waiting."
    }

    Write-Host "$(Get-Date): Hosting Database is Ready"
}

Function ConfigureRoleAdministrator([string] $roleadminusr, [string] $roleadminpwd)
{
    $isDomain = $false

    # Identify if user is a domain user account
    $values = $roleadminusr.Split('\');
    If ($values.Length -eq 1)
    {
        $domain = $env:COMPUTERNAME
        $username = $values[0]
    }
    ElseIf ($values.Length -eq 2)
    {
        If ([String]::Equals($values[0], ".") -Or
            [String]::Equals($values[0], [Environment]::MachineName, [StringComparison]::OrdinalIgnoreCase))
        {
            $isDomain = $false
            $domain = $env:COMPUTERNAME
            $username = $values[1]
        }
        Else
        {
            $isDomain = $true
            $domain = $values[0]
            $username = $values[1]
        }
    }
    Else
    {
        Throw New-Object ArgumentException "Invalid user name" "roleadminusr"
    }

    # Create user if specified user is not a domain account
    if ($isDomain -eq $false)
    {
        Try
        {
            $computer = [ADSI]"WinNT://$env:COMPUTERNAME"
            $user = $computer.Create("User", $username)
            $user.setpassword($roleadminpwd)
            $user.SetInfo()
        }
        Catch [System.Runtime.InteropServices.COMException]
        {
            # User already exists
            If ($_.Exception.ErrorCode -eq -2147022672)
            {
                Write-Host "$(Get-Date): User $domain\$username already exits."
                Write-Host "$(Get-Date): Updating password for User $domain\$username."
                $user = [ADSI]("WinNT://$env:COMPUTERNAME/$username,user")
                $user.setpassword($roleadminpwd)
                $user.SetInfo()
            }
            Else
            {
                Write-Host "$(Get-Date): Error creating user $domain\$username." -ForegroundColor Red

                Throw
            }
        }
    }

    # Add user to local administrators group

    #first translate the "Administrators" name to the name based on locale (make well known SID -> Name translation)

    $administratorsSID = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-32-544")
    $administratorsGroupName = $administratorsSID.Translate([System.Security.Principal.NTAccount]).Value

    # retrieve the short name eg in german translate VORDEFINIERT\Administratoren ->Administratoren
    # the translation should always return fully qualified name equivalent to BUILTIN\Administrators

    $localizedAdministratorsGroupName=$administratorsGroupName.Split("\\")[1]

    $adminGroup = [ADSI]("WinNT://$env:COMPUTERNAME/$localizedAdministratorsGroupName,group")

    Try
    {
        If ($isDomain -eq $true)
        {
            $adminGroup.add("WinNT://$domain/$username,user")
        }
        Else
        {
            $adminGroup.add("WinNT://$env:COMPUTERNAME/$username,user")
        }
    }
    Catch [System.Runtime.InteropServices.COMException]
    {
        If ($_.Exception.ErrorCode -eq -2147023518) # ERROR_MEMBER_IN_ALIAS 1378 (0x562)
        {
            Write-Host "$(Get-Date): User $domain\$username is already member of Administrators group."
        }
        Else
        {
            Write-Host "$(Get-Date): Error adding user $domain\$username to Administrators group." -ForegroundColor Red

            Throw
        }
    }
}