2 番目の Web サイト コントローラーのプロビジョニング

 

適用対象: Azure Pack Windows

Windows Azure Pack:Web サイトは最大 2 個の Web サイト コントローラーを使用できます。 高可用性の場合、この最大値を利用し、2 番目の Web サイト コントローラーをプロビジョニングすることを強くお勧めします。 これは、次の 2 つの方法のいずれかで行うことができます。

  • 新しいファームを作成する場合
  • 既存のファームにコントローラーを追加する

新しいファームに 2 つ目の Web サイト コントローラーを追加する (Update Release 6 以降を使用)

Windows Azure Pack Web サイト管理コンソールを使用して、新しいファームを構成するときに 2 つ目の Web サイト コントローラーを追加できます。

  1. コントローラーの種類を選択する場合は、[ サーバーをセカンダリ コントローラーとして既存の Websites クラウドに参加させる] を選択します。
  2. システム キーとデータベース接続文字列の一覧で、[構成] をクリックします。
  3. ポップアップ ウィンドウで、次のフィールドの値を入力します。
    • プライマリ コントローラー
    • ユーザー名
    • Password
  4. [ OK] を クリックして、2 つ目のコントローラーを構成します。

既存のファームに 2 つ目の Web サイト コントローラーを追加する

既存のファームにコントローラーを追加するには、次のスクリプトを使用します。

  • OnStartSecondaryController.cmd : 準備した Windows 2012 サーバーまたは仮想マシンに WebPlatform Installer (Web PI) をインストールします。 次に、HostingBootstrapperBootstrapper スクリプトと OnStartSecondaryController スクリプトを順に呼び出して、セカンダリ コントローラーのプロビジョニングを完了します。 必須のパラメーターには、セットアップで使用される SQL Server とコントローラーの管理者の資格情報が含まれます。

  • HostingBootstrapperBootstrapper.ps1 - Program Files\Microsoft\Web Platform Installer\WebpiCmd.exe を呼び出して、2 番目の Web サイト コントローラーをインストールします。 プライマリ コントローラーをインストールするときと同じ手順を使用しますが、コマンド ライン スイッチ /SuppressPostFinish を指定して構成ポータルを破棄します。

  • OnStartSecondaryController.ps1: プライマリ コントローラーからセカンダリ コントローラーに構成データをコピーします。構成データには、SystemCore キーや SiteRuntime キー、ホスティングおよびリソース メータリングの接続文字列が含まれます。 終了すると、WebFarmService を開始します。

  • Common.ps1: OnStartSecondaryController.ps1 スクリプトの補助的な機能を提供します。

重要

これらのスクリプトを実行するには、プライマリ コントローラーで Windows リモート管理 (WinRM) が有効になっている必要があります。

スクリプトを実行する手順

  1. セカンダリ コントローラーとなるサーバーのフォルダーにスクリプト ファイルをコピーします。

  2. スクリプトと同じフォルダーに WebPlatformInstaller.msi ファイルをコピーします。 これは OnStartSecondaryController.cmd スクリプトが Web PI のインストールを自動化するために必要です。

  3. 管理者権限で OnStartSecondaryController.cmd を実行し、次の表で説明されているパラメーターを指定します。 管理者特権は、適切な製品を Web PI のオートメーションによってインストールできるようにし、プライマリ コントローラーが WinRM でアクセスできるようにするために必要です。

    注意

    ワークグループのシナリオでは、プライマリ コントローラーで WinRM を有効にするか、OnStartSecondaryController.cmd スクリプトのコマンドを手動で実行することが必要になる場合があります。

OnStartSecondaryController.cmd

構文

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

パラメーター

パラメーター名 説明 メモ
feed 必要に応じて、コントローラーをインストールするために使用される Web PI フィードを指定します。 このパラメーターが指定されていない場合は、既定の Web PI プライマリ フィードが使用されます。
webSitesInstanceName データベース オブジェクトのプレフィックスとして使用されます。 インストールに含まれるデータベースのプレフィックス名と一致している必要があります。
sqlservername SQL Server のインスタンスの名前。
sqlsysadmin SQL Server のシステム管理者のユーザー アカウント名。 sysadmin サーバー ロールのメンバーである必要があります。
sqlsysadminpwd SQL Server のシステム管理者のユーザー アカウント パスワード。
controllerAdminUserName プロビジョニングする Web Farm Framework (WFF) の管理者アカウントの名前。 ドメイン アカウントである場合は、ローカル Administrators グループに追加されます。

サーバーがワークグループに属している場合、このユーザーが存在しないときにはユーザーを作成し、ローカル Administrators グループに追加しようとします。
controllerAdminPassword プロビジョニングする WFF 管理者アカウントのパスワード。

OnStartSecondaryController.cmd スクリプト

@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  

HostingBootstrapperBootstrapper.ps1

# 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  

OnStartSecondaryController.ps1

# 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  

Common.ps1

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

参照

Azure Pack Windowsデプロイ: Web サイト