WMI を使用した IIS 7.0 のワーカー プロセスとアプリケーション ドメインの管理

作成者 : Tim Ammann
発行日 : 2007 年 11 月 23 日 (作業者 : saad(英語))
更新日 : 2008 年 2 月 26 日 (作業者 : saad(英語))

はじめに

WMI スクリプトを使用すると、IIS 7.0 のワーカー プロセスとアプリケーション ドメイン (AppDomain) を比較的簡単に管理できます。IIS 7.0 のワーカー プロセスは、Windows プロセス起動サービス (WAS) によって作成され、w3wp.exe によって実行されます。ワーカー プロセスにはアプリケーション ドメインを含めることができます。アプリケーション ドメインは通常、.aspx ページへの要求に応じて作成されます。

この記事では、わずか数行の VBScript によって次のタスクを実行する方法について説明します。

  • ワーカー プロセスで現在実行中の要求の表示
  • すべてのワーカー プロセスの状態の取得
  • 特定のアプリケーション ドメイン、またはすべてのアプリケーション ドメインのアンロード
  • すべてのアプリケーション ドメインとそのプロパティの表示

最初の手順

   1. IIS とスクリプトを有効にします。

a. Windows Vista を使用している場合は、[コントロール パネル][プログラムと機能] から [Windows の機能] を開きます。[Web 管理ツール] の下の [IIS 管理スクリプトおよびツール] を選択して、スクリプトを有効にします。
b. Windows Server® 2008 を使用している場合は、[サーバー マネージャー] を開きます。役割の追加ウィザードを使用して IIS 7.0 Web サーバーをインストールします。[役割サービスの選択] ページの [管理ツール] セクションで、[IIS 管理スクリプトおよびツール] を選択します。

    2.  各種コマンドは管理者として実行します。管理者特権でコマンド プロンプト ウィンドウを開くには、[スタート] ボタン、[すべてのプログラム][アクセサリ] の順にクリックし、[コマンド プロンプト] を右クリックして [管理者として実行] をクリックします。管理者としてコマンド シェルを開くと、そのコマンド シェルから実行するすべてのアプリケーションは管理者として実行されます。

   3.  スクリプト ファイルは、.vbs 拡張子を付けてテキスト形式で保存します。それらは、"cscript.exe <scriptname>.vbs" という構文でコマンド プロンプトから実行できます。

   4.  開始する前に、AppCmd ツールを使用して、System32\inetsrv\config\applicationhost.config ファイルのバックアップを作成します。バックアップ コピーを作成しておくと、現バージョンに対して元のバージョンを上書きコピーすることで、IIS 7.0 を元の状態に復元できます。バックアップを作成するには、次の手順を実行します。

        a. 管理者特権でコマンド プロンプト ウィンドウを開きます。
       b. 「cd %Windir%\system32\inetsrv\」と入力します。
       c. 「appcmd add backup <backupName>」と入力して、ApplicationHost.config ファイルのバックアップを作成します。<backupName> には、バックアップ名を指定します。ここで指定したバックアップ名を持つディレクトリが、%Windir%\system32\inetsrv\backup ディレクトリの下に作成されます。名前を指定しないと、現在の日付と時刻を使用したディレクトリ名が自動的に生成されます。

ワーカー プロセス

ここでは、Web サーバー上の各ワーカー プロセスで現在実行中の要求を取得する方法について説明します。その後、各ワーカー プロセスの PID、状態、およびそれが属するアプリケーション プールを表示する方法を学びます。

実行中の要求の取得

IIS 7.0 のすばらしい新機能の 1 つに、ワーカー プロセスで現在実行中の要求を確認できることが挙げられます。それには、WorkerProcess.GetExecutingRequests メソッドを使用します。

WorkerProcess.GetExecutingRequests メソッドは、このメソッドの実行時に実行されていた要求のスナップショットを報告します。ほとんどの要求は非常にすばやく実行されるため、Web ブラウザーでメソッドを手動でテストするのは簡単ではありません。そのため、この目的でテストするための Web ページを作成します。

次のテキストをメモ帳にコピーし、Sleep.aspx というファイル名を付けてテキスト形式で保存します。  

<%  System.Threading.Thread.Sleep(30000)
Response.Write ("I'm finally finished...") %>

Sleep.aspx ファイルを、既定の Web サイトのコンテンツ ディレクトリに格納します (%systemdrive%\inetpub\wwwroot)。

作成した Sleep.aspx ファイルでは、Web ページに対する要求が 30 秒間かけて実行されるようになります。これにより、スクリプトを実行するのに十分な時間が確保され、GetExecutingRequests によって現在実行中の情報が表示されます。

GetExecutingRequests メソッドには、出力用のパラメーターとして空の配列変数を指定します。これには、HttpRequest オブジェクトが格納されます。要求ごとに処理を反復することによって、すべての要求の属性を表示できます。次のスクリプトでは、HttpRequest オブジェクトの出力を取得して、各要求の現在のモジュール、動詞、ホスト名、および URL を表示します。

次のスクリプトをメモ帳にコピーして、GetRequests.vbs というファイル名で保存してください。

Set oWebAdmin = GetObject("winmgmts:root\WebAdministration")
Set oWorkerProcesses = oWebAdmin.InstancesOf("WorkerProcess")
     
For Each oWorkerProcess In oWorkerProcesses
    ' Place the requests queued for a process into an array variable.
    oWorkerProcess.GetExecutingRequests arrReqs
    
    ' Show the number of requests queued.
    If IsNull(arrReqs) Then
        WScript.Echo "No currently executing requests."

    Else
        ' Display the number of requests.
        WScript.Echo "Number of currently executing requests: " & _
            UBound(arrReqs) + 1
        WScript.Echo
  
        ' List the properties of each request.
        For Each oRequest In arrReqs
            WScript.Echo "Module: " & "[" & oRequest.CurrentModule & "]"
            WScript.Echo "Verb:" & "[" & oRequest.Verb & "]"
            WScript.Echo "HostName: " & "[" & oRequest.HostName & "]"
            WScript.Echo "Url: " & "[" & oRequest.Url & "]"
            WScript.Echo
        Next
    End If
Next

管理者特権でコマンド プロンプト ウィンドウを開き、GetRequests.vbs ファイルを保存したディレクトリに移動します。

スクリプトを実行する前に、Web ブラウザーのアドレス バーに「http://localhost/sleep.aspx」と入力します。これによって、要求の実行が開始され、ブラウザーで Sleep.aspx ページが表示されるまで 30 秒の待機時間が設定されます。

ブラウザーがページの表示を待機している間に、今開いたコマンド プロンプト ウィンドウで次のコマンドを入力してスクリプトを実行します。

Cscript.exe GetRequests.vbs

サンプル出力

出力例を次に示します。

Number of currently executing requests: 2
Module: [ManagedPipelineHandler]
Verb:[GET]
HostName: [localhost]
Url: [/MyApp/]
Module: [ManagedPipelineHandler]
Verb:[GET]
HostName: [localhost]
Url: [/MyApp/default.aspx]

ワーカー プロセスの状態の取得

IIS 7.0 WMI プロバイダーの WorkerProcess オブジェクトには、ワーカー プロセスの状態 (開始、実行、または停止) を取得する GetState メソッドがあります。また、WorkerProcess には、この記事の内容に関連する 2 つのプロパティ (ApplicationPool と PID) もあります。ApplicationPool プロパティは、ワーカー プロセスが属するアプリケーション プールを示します。PID プロパティには、ワーカー プロセスを一意に識別するプロセス ID が含まれます。

次のコードを使用して、各ワーカー プロセスの PID、状態、およびアプリケーション プールを一覧表示できます。ワーカー プロセスが実行されていない場合は、スクリプトは何も表示せずに終了します。次のコードをメモ帳にコピーして、GetState.vbs というファイル名で保存してください。

' Connect to the WMI WebAdministration namespace. 
Set oWebAdmin = GetObject("winmgmts:root\WebAdministration") 
       
' Get the worker process instances. 
Set oWorkerProcesses = oWebAdmin.InstancesOf("WorkerProcess") 
       
' Get the ID of each worker process in the application pool and report its status. 
For Each oWorkerProcess In oWorkerProcesses 
       
    ' Report the worker process state via the GetStateDescription helper function. 
    WScript.Echo "WorkerProcess " & oWorkerProcess.ProcessID & ": " & _ 
        GetStateDescription(oWorkerProcess.GetState) 
    WScript.Echo "Application Pool: " & oWorkerProcess.AppPoolName
    WScript.Echo 
Next 
       
       
' The helper function translates the return value into text. 
Function GetStateDescription(StateCode) 
    Select Case StateCode 
        Case 0 
            GetStateDescription = "Starting" 
        Case 1 
            GetStateDescription = "Running" 
        Case 2 
            GetStateDescription = "Stopping" 
        Case 3 
            GetStateDescription = "Unknown" 
       
        Case Else 
            GetStateDescription = "Undefined value." 
    End Select 
End Function 

管理者特権でコマンド プロンプト ウィンドウを開き、GetState.vbs ファイルを保存したディレクトリに移動します。このコマンド プロンプト ウィンドウで次のコマンドを入力して、スクリプトを実行します。

Cscript.exe GetState.vbs

サンプル出力

次のような出力が得られます。

WorkerProcess 1336: Running 
Application Pool: DefaultAppPool 
       
WorkerProcess 3680: Running 

Application Pool: Classic .NET AppPool 
       
WorkerProcess 1960: Running 

Application Pool: NewAppPool

ここまでは、WMI スクリプトを使用してワーカー プロセスの情報を表示する方法を学んできました。次は、アプリケーション ドメインに関する情報を表示する方法について説明します。

アプリケーション ドメイン

ASP.NET ページに対する要求を初めて受け取ると、IIS 7.0 マネージ エンジン モジュールはメモリ内にアプリケーション ドメイン (AppDomain) を作成します。アプリケーション ドメインは、aspx ページ、またはマネージ コードを使用するすべてのページに対する要求を処理します。WMI を使用すると、アプリケーション ドメインのアンロードや列挙を簡単に行うことができます。ここでは、その方法について説明します。

特定のアプリケーション ドメインのアンロード

IIS 7.0 でのアプリケーション ドメインのアンロードは、IIS 6.0 とは多少異なります。IIS 6.0 の AppUnload コマンドではプロセス外の ASP アプリケーションがアンロードされましたが、IIS 7.0 の AppDomain.Unload メソッドは ASP.NET アプリケーション ドメインのみをアンロードします。AppUnload の機能がサポートしていた IIS 5.0 互換モードは IIS 7.0 には存在しないため、この機能は IIS 7.0 では除去されています。

特定のアプリケーション ドメインをアンロードするには、そのアプリケーション ドメインを一意に識別する必要があります。AppDomain オブジェクトには、ApplicationPath、ID、および SiteName という 3 つのキー プロパティがあります。ただし、一意に識別するためには、3 つのプロパティのいずれか 1 つで十分です。

ちなみに、AppDomain の ID プロパティは、番号ではなく、次のようなパスになります。

/LM/W3SVC/1/ROOT 

上記のパスの中の "1" は Site ID です (既定では、1 は既定の Web サイトに対応します)。サーバーのアプリケーション ドメインとそのプロパティの一覧を最初に生成する必要がある場合は、この記事で後述する「アプリケーション ドメインの列挙」を参照してください。

次のスクリプトは "Northwind" というアプリケーション ドメインをアンロードします。このスクリプトでは、ApplicationPath が一致するものが見つかるまで、すべてのアプリケーション ドメインに対して反復処理を実行します。コードをメモ帳にコピーし、"Northwind" を目的のアプリケーション ドメインのアプリケーション パスで置き換えて、AppDomainUnload.vbs という名前でファイルを保存してください。

管理者特権でコマンド プロンプト ウィンドウを開き、AppDomainUnload.vbs ファイルを保存したディレクトリに移動します。このコマンド プロンプト ウィンドウで次のコマンドを入力して、スクリプトを実行します。

Cscript.exe AppDomainUnload.vbs

Set oWebAdmin = GetObject("winmgmts:root\WebAdministration")
Set oAppDomains = oWebAdmin.ExecQuery("SELECT * FROM AppDomain")

' Unload only the Northwind application domain.
For Each oAppDomain In oAppDomains
    If oAppDomain.ApplicationPath = "/Northwind/" Then 
        oAppDomain.Unload
        Exit For 
    End If 
Next 

すべてのアプリケーション ドメインのアンロード

サーバー上のすべてのアプリケーション ドメインのアンロードは、さらに簡単です。すべてのアプリケーション ドメインを取得し、反復処理によって順にアンロードするだけです。

次の例は、IIS 7.0 Web サーバー上のすべてのアプリケーション ドメインをアンロードします。シンプルな WQL クエリを使用してアプリケーション ドメインを取得していることに注目してください (WQL は WMI バージョンの SQL です)。

コードをメモ帳にコピーして、AppDomainUnloadAll.vbs という名前でファイルを保存します。管理者特権でコマンド プロンプト ウィンドウを開き、AppDomainUnloadAll.vbs ファイルを保存したディレクトリに移動します。このコマンド プロンプト ウィンドウで次のコマンドを入力して、スクリプトを実行します。

Cscript.exe AppDomainUnloadAll.vbs

Set oWebAdmin = GetObject("winmgmts:root\WebAdministration")

' Get all the application domains on the Web server.
Set oAppDomains = oWebAdmin.ExecQuery("SELECT * FROM AppDomain")

' Unload all the application domains.
For Each oAppDomain In oAppDomains
    oAppDomain.Unload
Next 

WQL クエリ構文の代わりに、前述のワーカー プロセスの場合と同様に WMI の InstancesOf メソッドを使用することもできます。

Set oAppDomains = oWebAdmin.InstancesOf("AppDomain")

アプリケーション ドメインの列挙

前述のスクリプトと同じような方法で、現在実行中のすべてのアプリケーション ドメインとそのプロパティを表示できます。アプリケーション ドメインのプロパティは次のとおりです。

  • ApplicationPath
  • Id
  • IsIdle
  • PhysicalPath
  • ProcessId
  • SiteName

次のスクリプトは、それぞれのアプリケーション ドメインについて Physical Path プロパティ以外のすべてのプロパティを表示します。ただし、Physical Path プロパティも簡単に追加できます。便宜上、このスクリプトではキー プロパティと実行時プロパティを別々に表示します。

コードをメモ帳にコピーして、AppDomainProps.vbs という名前でファイルを保存します。管理者特権でコマンド プロンプト ウィンドウを開き、AppDomainProps.vbs ファイルを保存したディレクトリに移動します。このコマンド プロンプト ウィンドウで次のコマンドを入力して、スクリプトを実行します。

Cscript.exe AppDomainProps.vbs

'Connect to the WMI WebAdministration namespace
Set oWebAdmin = GetObject("winmgmts:root\WebAdministration")
Set oAppDomains = oWebAdmin.InstancesOf("AppDomain")
WScript.Echo "AppDomain Count: " & oAppDomains.Count
WScript.Echo 
ADCounter = 0
For Each oAppDomain In oAppDomains
    ADCounter = ADCounter + 1
    WScript.Echo "---- AppDomain " & ADCounter & " of " & _
                oAppDomains.Count & " ----" & vbCrLf
    WScript.Echo "[ Key properties ]"
    WScript.Echo "ID: " & oAppDomain.ID
    WScript.Echo "Site Name: " & oAppDomain.SiteName
    WScript.Echo "Application Path: " & oAppDomain.ApplicationPath
    WScript.Echo
    WScript.Echo "[ Run-time properties ]"
    WScript.Echo "Process ID: " & oAppDomain.ProcessID
    WScript.Echo "Is idle: " & oAppDomain.IsIdle
    WScript.Echo vbCrLf
Next 

サンプル出力

次のような出力が表示されます。

AppDomain Count: 3
---- AppDomain 1 of 3 ----
[ Key properties ]
ID: /LM/W3SVC/1/ROOT
Site Name: Default Web Site

Application Path: /

[ Run-time properties ]
Process ID: 3608
Is idle: False

---- AppDomain 2 of 3 ----
[ Key properties ]
ID: /LM/W3SVC/2/ROOT/ContosoApp
Site Name: ContosoSite
Application Path: /ContosoApp/

[ Run-time properties ]
Process ID: 3608
Is idle: True

---- AppDomain 3 of 3 ----
[ Key properties ]
ID: /LM/W3SVC/1/ROOT/Fabrikam
Site Name: Default Web Site
Application Path: /Fabrikam/

[ Run-time properties ]
Process ID: 2552
Is idle: False

    

まとめ

この記事では、IIS 7.0 のワーカー プロセスとアプリケーション ドメインの情報を取得するための基本的な WMI スクリプトの作成方法を示しました。それらを取得するために、WMI の InstanceOf メソッドと WQL クエリを使用しました。示されたタスクと使用したメソッドを次に簡単にまとめます。

  • ワーカー プロセスで現在実行中の要求の表示 : WorkerProcess.GetExecutingRequests
  • すべてのワーカー プロセスの状態の取得 : WorkerProcess.GetState
  • 特定のアプリケーション ドメイン、またはすべてのアプリケーション ドメインのアンロード : AppDomain.Unload

詳細については、IIS 7.0 WMI プロバイダーのリファレンス (英語)を参照してください。