Bar

Windows Server 2012 Essentials リモートWebアクセスがエラーになり、イベント ID 1309,1310が記録される場合の対処法

久しぶりにWindows Server 2012 EssentialsのリモートWebアクセス画面を開いたところ、「'/' アプリケーションでサーバー エラーが発生しました。」なるエラーが表示されました。
イベント ログを見ると同時刻にASP.NETのログがあり、イベント IDは1309と1310の2種類が記録されていました。
今回は、Windows Server 2012 Essentials リモートWebアクセスがエラーになり、イベント ID 1309,1310が記録される場合の対処法をメモ。
※OSはR2ではありません、ご注意ください。

現象

  • xxx.remotewebaccess.com/remote にアクセスするとIISのエラーが表示
  • '/' アプリケーションでサーバー エラーが発生しました。
  • ランタイム エラー

イベント ビューアを確認するとASP.NETのエラーが表示されました。
  • ソース: ASP.NET 4.0.30319.0
  • イベント ID: 1309
Event code: 3005 
Event message: ハンドルされていない例外が発生しました。 
Event time: 2016/07/12 10:41:05 
Event time (UTC): 2016/07/12 1:41:05 
Event ID: e8c4972c221b4d8187c739cf2bfe7a50 
Event sequence: 4 
Event occurrence: 1 
Event detail code: 0 
 
Application information: 
    Application domain: /LM/W3SVC/1/ROOT-1-131127612656881475 
    Trust level: Full 
    Application Virtual Path: / 
    Application Path: C:\Program Files\Windows Server\Bin\WebApps\Site\ 
    Machine name: サーバー名
 
Process information: 
    Process ID: 15776 
    Process name: w3wp.exe 
    Account name: IIS APPPOOL\RootApp 
 
Exception information: 
    Exception type: FileNotFoundException 
    Exception message: ファイルまたはアセンブリ 'Wssg.Web.Internal, Version=6.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。
   場所 Microsoft.WindowsServerSolutions.Web.RootSite._Default.InitializeCulture()
   場所 ASP.default_aspx.FrameworkInitialize()
   場所 System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   場所 System.Web.UI.Page.ProcessRequest()
   場所 System.Web.UI.Page.ProcessRequest(HttpContext context)
   場所 System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   場所 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Request information: 
    Request URL: https://グローバルIPアドレス:443/default.aspx 
    Request path: /default.aspx 
    User host address: xxx.xxx.xxx.xxx
    User:  
    Is authenticated: False 
    Authentication Type:  
    Thread account name: IIS APPPOOL\RootApp 
 
Thread information: 
    Thread ID: 7 
    Thread account name: IIS APPPOOL\RootApp 
    Is impersonating: False 
    Stack trace:    場所 Microsoft.WindowsServerSolutions.Web.RootSite._Default.InitializeCulture()
   場所 ASP.default_aspx.FrameworkInitialize()
   場所 System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   場所 System.Web.UI.Page.ProcessRequest()
   場所 System.Web.UI.Page.ProcessRequest(HttpContext context)
   場所 System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   場所 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
  • ソース: ASP.NET 4.0.30319.0
  • イベント ID: 1310
Event code: 3008 
Event message: 構成エラーが発生しました。 
Event time: 2016/07/12 10:16:29 
Event time (UTC): 2016/07/12 1:16:29 
Event ID: 846ac414f34f475dac7920582b102669 
Event sequence: 2 
Event occurrence: 1 
Event detail code: 0 
 
Application information: 
    Application domain: /LM/W3SVC/1/ROOT/Remote-1-131127597865400563 
    Trust level: Full 
    Application Virtual Path: /Remote 
    Application Path: C:\Program Files\Windows Server\Bin\WebApps\RemoteAccess\ 
    Machine name: サーバー名
 
Process information: 
    Process ID: 2784 
    Process name: w3wp.exe 
    Account name: NT AUTHORITY\NETWORK SERVICE 
 
Exception information: 
    Exception type: HttpException 
    Exception message: 呼び出しのターゲットが例外をスローしました。 (C:\Program Files\Windows Server\Bin\WebApps\RemoteAccess\web.config line 143)
   場所 System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext context, HttpApplication app)
   場所 System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers)
   場所 System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context)
   場所 System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context)
   場所 System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext)

呼び出しのターゲットが例外をスローしました。 (C:\Program Files\Windows Server\Bin\WebApps\RemoteAccess\web.config line 143)
   場所 System.Web.Configuration.ProvidersHelper.InstantiateProvider(ProviderSettings providerSettings, Type providerType)
   場所 System.Web.Configuration.ProvidersHelper.InstantiateProviders(ProviderSettingsCollection configProviders, ProviderCollection providers, Type providerType)
   場所 System.Web.Security.Membership.InitializeSettings(Boolean initializeGeneralSettings, RuntimeConfig appConfig, MembershipSection settings)
   場所 System.Web.Security.Membership.Initialize()
   場所 System.Web.Security.Membership.get_Provider()
   場所 Microsoft.WindowsServerSolutions.Web.Security.AuthenticationHelper.add_PreLogOn(EventHandler value)
   場所 Microsoft.WindowsServerSolutions.Web.RemoteAccessSite.Global.Application_Start(Object sender, EventArgs e)

呼び出しのターゲットが例外をスローしました。
   場所 System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
   場所 System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
   場所 System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
   場所 System.Activator.CreateInstance(Type type, Boolean nonPublic)
   場所 System.Activator.CreateInstance(Type type)
   場所 System.Web.Configuration.ProvidersHelper.InstantiateProvider(ProviderSettings providerSettings, Type providerType)

ファイルまたはアセンブリ 'WssgCertMgmt, Version=6.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。

Server stack trace: 
   場所 Microsoft.WindowsServerSolutions.Certificates.CertManaged.TryGetLocalMachineCert()
   場所 Microsoft.WindowsServerSolutions.Certificates.CertManaged.GetLocalMachineCert()
   場所 Microsoft.WindowsServerSolutions.Common.ProviderFramework.ProductConfigurator._CreateProxyEndpoint(Uri address, Type contractType, ProviderEndpointBehaviorAttribute endpointBehavior)
   場所 Microsoft.WindowsServerSolutions.Common.ProviderFramework.Internal.ProviderFrameworkConfigurator.GetDuplexChannelFactory[T](ICollection`1 behaviors, ProviderInfo info, Object callback, NetworkCredential credential)
   場所 Microsoft.WindowsServerSolutions.Common.ProviderFramework.ProviderRegistryConnectionMgmt`1._CreateChannel(String targetComputer, IRegistryCallback callback, ProviderEndpointBehaviorAttribute endpointBehavior)
   場所 Microsoft.WindowsServerSolutions.Common.ProviderFramework.ProviderRegistryConnectionMgmt`1._GetFactory(String targetComputer, IRegistryCallback callback, ProviderEndpointBehaviorAttribute endpointBehavior)
   場所 Microsoft.WindowsServerSolutions.Common.ProviderFramework.ProviderRegistryConnectionMgmt`1._CreateRealProxy()
   場所 Microsoft.WindowsServerSolutions.Common.ProviderFramework.Internal.AutoReconnecter`1._BeginConnect()
   場所 Microsoft.WindowsServerSolutions.Common.ProviderFramework.ProviderRegistryConnectionMgmt`1.ConnectWhenAvailable(Int32 spinWaitMillis, Action operation, IRegistryCallback informOfProviderUpdateCallback)
   場所 Microsoft.WindowsServerSolutions.Common.ProviderFramework.ConnectorFactory.get__PrsProxy()
   場所 Microsoft.WindowsServerSolutions.Common.ProviderFramework.ConnectorFactory.SetupConnector[T](ProviderConnector`1 providerConnector)
   場所 Microsoft.WindowsServerSolutions.Common.ProviderFramework.ConnectorFactory.GetConnector[T](String identifier, Object callback)
   場所 Microsoft.WindowsServerSolutions.Common.ProviderFramework.ConnectorFactory.GetServerConnector[T](String identifier, Object callback, NetworkCredential credential)
   場所 Microsoft.WindowsServerSolutions.Users.Internal.UserBackEnd.<>c__DisplayClass6.b__2()
   場所 System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]& outArgs)
   場所 System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage msg, IMessageSink replySink)

Exception rethrown at [0]: 
   場所 System.Runtime.Remoting.Proxies.RealProxy.EndInvokeHelper(Message reqMsg, Boolean bProxyCase)
   場所 System.Runtime.Remoting.Proxies.RemotingProxy.Invoke(Object NotUsed, MessageData& msgData)
   場所 System.Action.EndInvoke(IAsyncResult result)
   場所 Microsoft.WindowsServerSolutions.Users.Internal.UserBackEnd.CreateConnector(TimeSpan timeSpan)
   場所 Microsoft.WindowsServerSolutions.Users.Internal.UserBackEnd.Microsoft.WindowsServerSolutions.Users.Internal.IUserBackEnd.ConnectAsync(TimeSpan timeSpan)
   場所 Microsoft.WindowsServerSolutions.Users.Internal.UserBackEnd.Microsoft.WindowsServerSolutions.Users.Internal.IUserBackEnd.Connect(TimeSpan timeSpan)
   場所 Microsoft.WindowsServerSolutions.Users.UserMgmtManager.Connect()
   場所 Microsoft.WindowsServerSolutions.Web.Security.HSBSMembershipProvider..ctor()

Request information: 
    Request URL: https://xxx.remotewebaccess.com:443/remote 
    Request path: /remote 
    User host address: xxx.xxx.xxx.xxx 
    User:  
    Is authenticated: False 
    Authentication Type:  
    Thread account name: NT AUTHORITY\NETWORK SERVICE 
 
Thread information: 
    Thread ID: 10 
    Thread account name: NT AUTHORITY\NETWORK SERVICE 
    Is impersonating: False 
    Stack trace:    場所 System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext context, HttpApplication app)
   場所 System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers)
   場所 System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context)
   場所 System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context)
   場所 System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext)

原因

Microsoft サポートによると、SFC(System File Checker)コマンドに/scannow オプションを付けて実行すると、リモートWebアクセス機能が壊れるそうです。
The web configuration file may become corrupted when you run the SFC command in Windows Server 2012 Essentials
確かに以前sfc.exe /scannow を実行しました・・・

対処法

Microsoft サポートに対処法があり、PowerShell を使います。
# ExpandEnvironmentVariablesメソッドによりWindows Server EssentialsのBinフォルダを取得
# %programfiles%を展開するためExpandEnvironmentVariablesメソッドを使っている
$BinDir = [System.Environment]::ExpandEnvironmentVariables("%programfiles%\windows server\bin")

# ExpandEnvironmentVariablesメソッドによりWindows Server EssentialsのWebAppsフォルダを取得
$WebDir = [System.Environment]::ExpandEnvironmentVariables("%programfiles%\windows server\bin\WebApps")

# WebAppsフォルダ配下の全ファイルを取得
$WebDir = get-childitem $WebDir –recurse

# $WebDir配下のweb.config ファイルを抽出
$List = $WebDir | where {$_.name -eq "web.config"}

foreach($listItem in $List){ if($listItem.DirectoryName -match "MacWebService") {continue;} ($a= Get-Content $listItem.FullName); $a = $a -replace "%SBSPRODUCTBINPLACEHOLDER%", $BinDir; remove-item $listItem.FullName; $f = [io.path]::Combine($listItem.DirectoryName, "Web.config"); $a >> $f}
最後の呪文っぽい内容は以下の処理を実行しています。
foreach($listItem in $List){
    # ディレクトリ名がMacWebServiceならば、次の処理へ
    if($listItem.DirectoryName -match "MacWebService"){
        continue;
    }

    # web.configのフルパスを指定し、ファイルの中身を取得し$a変数に格納
    $a= Get-Content $listItem.FullName

    # %SBSPRODUCTBINPLACEHOLDER% の文字を C:\Program Files\windows server\bin に置換
    $a = $a -replace "%SBSPRODUCTBINPLACEHOLDER%", $BinDir

    # web.configを削除
    remove-item $listItem.FullName

    # [io.path]::Combineを使ってディレクトリ名とファイル名を結合する
    $f = [io.path]::Combine($listItem.DirectoryName, "Web.config")

    # 文字列$a を ファイル$fに出力
    $a >> $f
}

PowerShell スクリプトを実行後、無事リモートWebアクセスの画面が表示されました。
Windows Server 2012 Essentialsでsfc コマンドを実行する時は要注意ですね・・・