Verwalten von Arbeitsprozessen und AppDomains in IIS 7 mit WMI

von Tim Ammann

Mit WMI-Skripts können Sie Arbeitsprozesse und Anwendungsdomänen (AppDomains) in IIS relativ einfach verwalten. IIS-Arbeitsprozesse werden vom Windows-Prozessaktivierungsdienst (WINDOWS Process Activation Service, WAS) und von W3wp.exe ausgeführt. Arbeitsprozesse können AppDomains enthalten, die in der Regel als Reaktion auf eine Anforderung für eine .aspx-Seite erstellt werden.

In diesem Artikel wird beschrieben, wie Sie mit nur wenigen Zeilen VBScript die folgenden Aufgaben ausführen:

  • Anzeigen der aktuell ausgeführten Anforderungen für einen Arbeitsprozess
  • Abrufen des Status aller Arbeitsprozesse
  • Entladen einer bestimmten AppDomain oder aller AppDomains
  • Alle AppDomains und deren Eigenschaften anzeigen

Erste Schritte

  1. Stellen Sie sicher, dass IIS und Skripts aktiviert sind.

    a. Wenn Sie Windows Vista verwenden, öffnen Sie die Systemsteuerung, Programme und Features und dann Windows-Features. Wählen Sie unter „Webverwaltungstools“ die Option „IIS-Verwaltungsskripts und -tools“ aus, um Skripts zu aktivieren. b. Wenn Sie Windows Server® 2008 verwenden, öffnen Sie den Server-Manager. Verwenden Sie den Assistenten zum Hinzufügen von Rollen, um den IIS-Webserver zu installieren. Wählen Sie auf der Seite Rollendienste auswählen im Abschnitt Verwaltungstools die Option „IIS-Verwaltungsskripts und -tools“ aus.

  2. Führen Sie Befehle als Administrator aus. Klicken Sie zum Öffnen eines Eingabeaufforderungsfensters mit erhöhten Rechten auf Start, zeigen Sie auf Alle Programme, klicken Sie auf Zubehör, klicken Sie mit der rechten Maustaste auf Eingabeaufforderung, und klicken Sie anschließend auf Als Administrator ausführen. Wenn Sie eine Befehlsshell als Administrator öffnen, werden alle Anwendungen, die Sie über diese Befehlsshell ausführen, als Administrator ausgeführt.

  3. Speichern Sie die Skriptdateien im Textformat mit der Erweiterung .vbs. Sie können an der Eingabeaufforderung mithilfe der Syntax „cscript.exe <scriptname>.vbs“ ausgeführt werden.

  4. Bevor Sie beginnen, erstellen Sie eine Sicherung der Datei System32\inetsrv\config\applicationhost.config mit dem AppCmd-Tool. Mit der Sicherungskopie können Sie den ursprünglichen Zustand von IIS wiederherstellen, indem Sie einfach die ursprüngliche Version auf die neue Version kopieren. Führen Sie die folgenden Schritte aus, um eine Sicherung zu erstellen:

    a. Öffnen Sie ein Eingabeaufforderungsfenster mit erhöhten Rechten.
    b. Geben Sie cd %Windir%\system32\inetsrv\c.appcmd add backup backupName ein, um die Datei ApplicationHost.config zu sichern, wobei backupName der Name ist, den Sie für die Sicherung angeben. Ein Verzeichnis mit dem von Ihnen angegebenen Sicherungsnamen wird unter dem %Windir%\system32\inetsrv\backup-Verzeichnis erstellt. Wenn Sie keinen Namen angeben, generiert appcmd automatisch einen Verzeichnisnamen mithilfe des aktuellen Datums und der aktuellen Uhrzeit.

Arbeitsprozesse

In diesem Abschnitt wird gezeigt, wie Sie die aktuell ausgeführten Anforderungen für jeden Arbeitsprozess auf einem Webserver abrufen. Anschließend erfahren Sie, wie Sie die einzelnen Arbeitsprozesse PID, Status und den Anwendungspool anzeigen, zu dem er gehört.

Abrufen von Ausführungsanforderungen

Ein spannendes neues Feature von IIS ist die Möglichkeit, die Anforderungen anzuzeigen, die derzeit in einem Arbeitsprozess ausgeführt werden. Dazu können Sie die WorkerProcess.GetExecutingRequests-Methode verwenden.

Die WorkerProcess.GetExecutingRequests-Methode meldet eine Momentaufnahme der Anforderungen, die zum Zeitpunkt der Ausführung der Methode ausgeführt wurden. Da die meisten Anforderungen sehr schnell ausgeführt werden, ist es möglicherweise nicht einfach, die Methode manuell mit einem Webbrowser zu testen. Aus diesem Grund erstellen Sie nur für diesen Zweck eine Webseite.

Verwenden Sie Editor, um den folgenden Text in eine Textdatei einzufügen. Speichern Sie die Datei dann mit dem Namen Sleep.aspx.

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

Verschieben Sie die Sleep.aspx-Datei in das Inhaltsverzeichnis der Standardwebsite: %systemdrive%\inetpub\wwwroot.

Die von Ihnen erstellte Datei Sleep.aspx erzwingt, dass die Anforderung der Webseite 30 Sekunden zur Ausführung benötigt. Dadurch erhalten Sie Zeit zum Ausführen eines Skripts, das GetExecutingRequests in Aktion anzeigt.

Die GetExecutingRequests-Methode verwendet eine leere Arrayvariable als OUT-Parameter, die dann mit HttpRequest-Objekten gefüllt wird. Sie können diese Anforderungen durchlaufen, um die Attribute für jede Anforderung anzuzeigen. Das folgende Skript verwendet die HttpRequest-Objektausgabe und zeigt das aktuelle Modul, das Verb, den Hostnamen und die URL für jede Anforderung an.

Kopieren Sie das folgende Skript zu Editor, und speichern Sie es unter dem Dateinamen 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

Öffnen Sie ein Eingabeaufforderungsfenster mit erhöhten Rechten, und navigieren Sie zu dem Verzeichnis, in dem Sie die Datei GetRequests.vbs gespeichert haben.

Geben Sie vor dem Ausführen des Skripts http://localhost/sleep.aspx in die Adressleiste eines Webbrowsers ein. Dadurch wird die Ausführung der Anforderung gestartet und der Browser läuft 30 Sekunden lang, während er darauf wartet, die Sleep.aspx-Seite zu rendern.

Während der Browser noch auf das Rendern der Seite wartet, führen Sie das Skript aus, indem Sie Folgendes in das soeben geöffnete Eingabeaufforderungsfenster eingeben:

Cscript.exe GetRequests.vbs

Beispielausgabe

Die angezeigte Ausgabe sollte wie folgt aussehen.

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

Abrufen des Status eines Arbeitsprozesses

Das WorkerProcess-Objekt im IIS-WMI-Anbieter verfügt über eine GetState-Methode, die anzeigt, ob ein Arbeitsprozess gestartet, ausgeführt oder beendet wird. WorkerProcess hat auch zwei Eigenschaften, die uns hier interessieren: ApplicationPool und PID. Die ApplicationPool-Eigenschaft stellt den Anwendungspool dar, zu dem der Arbeitsprozess gehört. Die PID-Eigenschaft enthält die Prozess-ID, die den Arbeitsprozess eindeutig identifiziert.

Sie können den folgenden Code verwenden, um jede PID und jeden Zustand des Arbeitsprozesses und dessen Anwendungspool aufzulisten. Wenn keine Arbeitsprozesse ausgeführt werden, wird das Skript automatisch beendet. Kopieren Sie den Code in Editor, und speichern Sie ihn unter dem Dateinamen 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

Öffnen Sie ein Eingabeaufforderungsfenster mit erhöhten Rechten, und navigieren Sie zu dem Verzeichnis, in dem Sie die Datei GetState.vbs gespeichert haben. Führen Sie das Skript aus, indem Sie Folgendes in das soeben geöffnete Eingabeaufforderungsfenster eingeben:

Cscript.exe GetState.vbs

Beispielausgabe

Ihre Ausgabe sollte dieser Ausgabe ähneln:

WorkerProcess 1336: Running 
Application Pool: DefaultAppPool 
       
WorkerProcess 3680: Running 
Application Pool: Classic .NET AppPool 
       
WorkerProcess 1960: Running 
Application Pool: NewAppPool

Nachdem Sie nun gelernt haben, WMI-Skripte zu verwenden, um die Geheimnisse von Arbeitsprozessen zu lüften, können Sie dies auch für Anwendungsdomänen tun.

AppDomains

Wenn eine Anforderung für eine ASP.NET Seite zum ersten Mal empfangen wird, erstellt das Modul für das verwaltete IIS-Modul eine Anwendungsdomäne (AppDomain) im Arbeitsspeicher. Die AppDomain verarbeitet Anforderungen für ASPX-Seiten oder eine beliebige Seite, die verwalteten Code verwendet. Das Entladen und Aufzählen von AppDomains mithilfe von WMI ist einfach, und in diesem Abschnitt wird gezeigt, wie Sie beides tun.

Entladen einer bestimmten AppDomain

Das Entladen von AppDomain in IIS 7 und höher funktioniert etwas anders als in IIS 6.0. Während der IIS 6.0-Befehl AppUnload ASP-Anwendungen außerhalb des Prozesses entlädt, entlädt die Methode AppDomain.Unload von IIS 7 und höher nur ASP.NET-Anwendungsdomänen. Die AppUnload-Funktion ist verschwunden, da der unterstützte IIS 5.0-Kompatibilitätsmodus in IIS 7 und höher nicht mehr vorhanden ist.

Zum Entladen einer bestimmten AppDomain müssen Sie in der Lage sein, sie eindeutig zu identifizieren. AppDomain-Objekte verfügen über drei Schlüsseleigenschaften: ApplicationPath, ID und SiteName. Eine davon reicht jedoch möglicherweise für Ihre Zwecke aus.

Übrigens ist die Eigenschaft AppDomain-ID keine Zahl, sondern ein Pfad, der wie folgt aussieht:

/LM/W3SVC/1/ROOT

Die „1“ im aufgelisteten Pfad ist die Website-ID (standardmäßig entspricht 1 der Standardwebsite.) Wenn Sie zuerst eine Liste der AppDomains ihres Servers und deren Eigenschaften generieren müssen, lesen Sie den Abschnitt „Aufzählen von AppDomains“ weiter unten in diesem Artikel.

Das nächste Skript entlädt die AppDomain mit dem Namen „Northwind“. Das Skript durchläuft die verfügbaren AppDomains, bis es das Skript mit dem entsprechenden ApplicationPath findet. Kopieren Sie den Code zu Editor, ersetzen Sie „Northwind“ durch den AppDomain-Anwendungspfad Ihrer Wahl, und speichern Sie die Datei mit dem Namen AppDomainUnload.vbs.

Öffnen Sie ein Eingabeaufforderungsfenster mit erhöhten Rechten, und navigieren Sie zu dem Verzeichnis, in dem Sie die Datei AppDomainUnload.vbs gespeichert haben. Führen Sie das Skript aus, indem Sie Folgendes in das soeben geöffnete Eingabeaufforderungsfenster eingeben:

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

Entladen aller AppDomains

Das Entladen aller AppDomains auf einem Server ist noch einfacher: Sie rufen sie einfach ab, durchlaufen sie und entladen sie wiederum.

Im folgenden Beispiel werden alle Anwendungsdomänen auf einem IIS-Webserver entladen. Beachten Sie, wie eine einfache WQL-Abfrage (WQL ist die WMI-Version von SQL) verwendet wird, um die AppDomains abzurufen.

Kopieren Sie den Code zu Editor, und speichern Sie die Datei mit dem Namen AppDomainUnloadAll.vbs. Öffnen Sie ein Eingabeaufforderungsfenster mit erhöhten Rechten, und navigieren Sie zu dem Verzeichnis, in dem Sie die Datei AppDomainUnloadAll.vbs gespeichert haben. Führen Sie das Skript aus, indem Sie Folgendes in das soeben geöffnete Eingabeaufforderungsfenster eingeben:

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

Als Alternative zur WQL-Abfragesyntax können Sie die WMI InstancesOf-Methode wie zuvor mit WorkerProcess verwenden:

Set oAppDomains = oWebAdmin.InstancesOf("AppDomain")

Aufzählen von AppDomains

Sie können alle derzeit ausgeführten AppDomains und deren Eigenschaften anzeigen, indem Sie einen Ansatz verwenden, der dem der vorherigen Skripts ähnelt. Hier ist eine Liste der AppDomain-Eigenschaften:

  • ApplicationPath
  • Kennung
  • IsIdle
  • PhysicalPath
  • ProcessId
  • SiteName

Das folgende Skript zeigt alle Eigenschaften für jede AppDomain mit Ausnahme der Eigenschaft Physischer Pfad, aber Sie können dies auf einfache Weise hinzufügen. Aus Gründen der Einfachheit zeigt das Skript die Schlüssel- und Laufzeiteigenschaften separat an.

Kopieren Sie den Code zu Editor, und speichern Sie die Datei mit dem Namen AppDomainProps.vbs. Öffnen Sie ein Eingabeaufforderungsfenster mit erhöhten Rechten, und navigieren Sie zu dem Verzeichnis, in dem Sie die Datei AppDomainProps.vbs gespeichert haben. Führen Sie das Skript aus, indem Sie Folgendes in das soeben geöffnete Eingabeaufforderungsfenster eingeben:

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

Beispielausgabe

Ihre Ausgabe sollte wie folgt aussehen:

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

Zusammenfassung

In diesem Artikel wurden einige grundlegende WMI-Skripttechniken zum Abrufen von Informationen zu IIS-Arbeitsprozessen und AppDomains gezeigt. Die WMI InstanceOf-Methode und WQL-Abfragen wurden verwendet, um diese abzurufen. Hier ist eine kurze Übersicht über die vorgestellten Aufgaben und die verwendeten Methoden:

  • Anzeigen der aktuell ausgeführten Anforderungen für einen Arbeitsprozess: WorkerProcess.GetExecutingRequests
  • Abrufen des Status aller Arbeitsprozesse: WorkerProcess.GetState
  • Entladen einer bestimmten AppDomain oder aller AppDomains: AppDomain.Unload