Compartir a través de


Administración de procesos de trabajo y AppDomains en IIS 7 con WMI

por Tim Ammann

El scripting WMI le permite administrar procesos de trabajo y dominios de aplicación (AppDomains) en IIS con relativa facilidad. Los procesos de trabajo de IIS se generan mediante el Servicio de activación de procesos de Windows (WAS) y se ejecutan mediante W3wp.exe. Los procesos de trabajo pueden contener AppDomains que normalmente se crean en respuesta a una solicitud de una página .aspx.

En este artículo se describe cómo realizar, con solo unas pocas líneas de VBScript, las siguientes tareas:

  • Visualizar las solicitudes que se están ejecutando actualmente para un proceso de trabajo
  • Obtener el estado de todos los procesos de trabajo
  • Descargar un AppDomain específico o todos los AppDomains
  • Mostrar todos los AppDomains y sus propiedades

Primeros pasos

  1. Asegúrese de que IIS y el scripting están habilitados.

    a. Si usa Windows Vista, abra panel de control, Programas y características y, a continuación, características de Windows. En "Herramientas de administración web", seleccione "Scripts y herramientas de administración de IIS" para habilitar el scripting. b. Si usa Windows Server® 2008, abra el Administrador del servidor. Use el Asistente para agregar roles para instalar el servidor web de IIS. En la página Seleccionar servicios de rol, en la sección Herramientas de administración, seleccione "Scripts y herramientas de administración de IIS".

  2. Ejecute los comandos como administrador. Para abrir la ventana del símbolo del sistema con privilegios elevados, haga clic en Inicio, seleccione Todos los programas, Accesorios, haga clic con el botón secundario en Símbolo del sistema y, a continuación, haga clic en Ejecutar como administrador. Si abre un shell de comandos como administrador, todas las aplicaciones que ejecute desde ese shell de comandos se ejecutarán como administrador.

  3. Guarde los archivos de script en formato de texto con una extensión .vbs. Se pueden ejecutar en el símbolo del sistema mediante la sintaxis "cscript.exe <scriptname>.vbs".

  4. Antes de empezar, realice una copia de seguridad del archivo System32\inetsrv\config\applicationhost.config con la herramienta AppCmd. La copia de seguridad le permitirá restaurar IIS a su estado original simplemente copiando la versión original en la posterior. Para realizar una copia de seguridad, siga estos pasos:

    a. Abra una ventana del símbolo del sistema con permisos elevados.
    b. Escriba cd %Windir%\system32\inetsrv\ c.Type appcmd add backup backupName para hacer una copia de seguridad del archivo ApplicationHost.config, donde backupName es el nombre que especifique para la copia de seguridad. Un directorio con el nombre de copia de seguridad que especifique se creará en el directorio %Windir%\system32\inetsrv\backup. Si no especifica un nombre, appcmd generará automáticamente un nombre de directorio con la fecha y hora actuales.

Procesos de trabajo

En esta sección se muestra cómo recuperar las solicitudes que se están ejecutando actualmente para cada proceso de trabajo en un servidor web. A continuación, aprenderá a mostrar el PID, el estado y el grupo de aplicaciones al que pertenece cada proceso de trabajo.

Obtención de solicitudes en ejecución

Una nueva característica interesante de IIS es la capacidad de ver las solicitudes que se están ejecutando actualmente en un proceso de trabajo. Puede hacerlo con el método WorkerProcess.GetExecutingRequests.

El método WorkerProcess.GetExecutingRequests informa de forma instantánea de las solicitudes que se estaban ejecutando en el momento en que se ejecutó el método. Dado que la mayoría de las solicitudes se ejecutan muy rápidamente, puede que no sea fácil probar el método manualmente con un explorador web. Por este motivo, creará una página web solo para este propósito.

Use el Bloc de notas para colocar el texto siguiente en un archivo de texto. A continuación, guarde el archivo con el nombre Sleep.aspx.

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

Coloque el archivo Sleep.aspx en el directorio de contenido del sitio web predeterminado: %systemdrive%\inetpub\wwwroot.

El archivo Sleep.aspx que creó obliga a que la solicitud de la página web tarde 30 segundos en ejecutarse. Esto le dará tiempo para ejecutar un script que mostrará GetExecutingRequests en acción.

El método GetExecutingRequests toma una variable de matriz vacía como un parámetro OUT, que luego rellena con objetos HttpRequest. Puede recorrer en iteración estas solicitudes para mostrar los atributos de cada solicitud. El siguiente script toma la salida del objeto HttpRequest y muestra el módulo actual, el verbo, el nombre de host y la dirección URL de cada solicitud.

Copie el siguiente script en el Bloc de notas y guárdelo con el nombre de archivo 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

Abra una ventana del símbolo del sistema con privilegios elevados y vaya al directorio en el que guardó el archivo GetRequests.vbs.

Antes de ejecutar el script, escriba http://localhost/sleep.aspx en la barra de direcciones de un explorador web. Esto iniciará la ejecución de la solicitud y dejará el explorador cargando durante 30 segundos mientras espera a representar la página de Sleep.aspx.

Mientras el explorador sigue esperando para representar la página, ejecute el script escribiendo lo siguiente en la ventana del símbolo del sistema que acaba de abrir:

Cscript.exe GetRequests.vbs

Salida de ejemplo

La salida que verá debe ser similar a la siguiente.

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

Obtención del estado de un proceso de trabajo

El objeto WorkerProcess del proveedor WMI de IIS tiene un método GetState que revela si un proceso de trabajo se está iniciando, ejecutando o deteniendo. WorkerProcess también tiene dos propiedades que nos interesan aquí: ApplicationPool y PID. La propiedad ApplicationPool representa el grupo de aplicaciones al que pertenece el proceso de trabajo. La propiedad PID contiene el identificador de proceso que identifica de forma única el proceso de trabajo.

Puede usar el código siguiente para enumerar cada PID y estado del proceso de trabajo y su grupo de aplicaciones. Si no se está ejecutando ningún proceso de trabajo, el script se cerrará de forma silenciosa. Copie el código en el Bloc de notas y guárdelo con el nombre de archivo 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

Abra una ventana del símbolo del sistema con privilegios elevados y vaya al directorio en el que guardó el archivo GetState.vbs. Ejecute el script escribiendo lo siguiente en la ventana del símbolo del sistema que acaba de abrir:

Cscript.exe GetState.vbs

Salida de ejemplo

La salida debe ser similar a la siguiente:

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

Ahora que ha aprendido a usar el scripting WMI para revelar los secretos de los procesos de trabajo, haga lo mismo para los dominios de aplicación.

Dominios de aplicaciones

La primera vez que se recibe una solicitud de una página de ASP.NET, el módulo del motor administrado de IIS crea un dominio de aplicación (AppDomain) en memoria. AppDomain procesa solicitudes de páginas aspx o cualquier página que use código administrado. Descargar y enumerar AppDomains mediante WMI es fácil y en esta sección se muestra cómo hacerlo.

Descarga de un AppDomain específico

La descarga de AppDomain en IIS 7 y versiones posteriores funciona de forma algo diferente que en IIS 6.0. Mientras que el comando AppUnload de IIS 6.0 descargó aplicaciones ASP fuera de proceso, el método IIS 7 y versiones posteriores de AppDomain.Unload solo descarga dominios de aplicación de ASP.NET. La funcionalidad AppUnload ha desaparecido porque el modo de compatibilidad de IIS 5.0 al que admitía ya no está presente en IIS 7 y versiones posteriores.

Para descargar un AppDomain específico, debe poder identificarlo de forma única. Los objetos AppDomain tienen tres propiedades clave: ApplicationPath, ID y SiteName. Sin embargo, solo una de estas puede ser suficiente para sus propósitos.

Por cierto, la propiedad AppDomain ID no es un número, sino una ruta de acceso similar a la siguiente:

/LM/W3SVC/1/ROOT

"1" en la ruta de acceso que aparece es el identificador de sitio (de forma predeterminada, 1 corresponde al sitio web predeterminado). Si primero debe generar una lista de AppDomains del servidor y sus propiedades, consulte la sección "Enumeración de AppDomains" más adelante en este artículo.

El siguiente script descarga el AppDomain denominado "Northwind". El script recorre en iteración los AppDomains disponibles hasta que encuentre el que coincida con ApplicationPath. Copie el código en el Bloc de notas, reemplace "Northwind" por la ruta de acceso de la aplicación AppDomain que prefiera y guarde el archivo con el nombre AppDomainUnload.vbs.

Abra una ventana del símbolo del sistema con privilegios elevados y vaya al directorio en el que guardó el archivo AppDomainUnload.vbs. Ejecute el script escribiendo lo siguiente en la ventana del símbolo del sistema que acaba de abrir:

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

Descarga de todos los AppDomains

Descargar todos los AppDomains en un servidor es aún más fácil: solo tiene que recuperarlos, recorrerlos en iteración y descargar cada uno a su vez.

En el ejemplo siguiente se descargan todos los dominios de aplicación en un servidor web de IIS. Tenga en cuenta cómo se usa una consulta WQL simple (WQL es la versión de WMI de SQL) para recuperar los AppDomains.

Copie el código en el Bloc de notas y guarde el archivo con el nombre AppDomainUnloadAll.vbs. Abra una ventana del símbolo del sistema con privilegios elevados y vaya al directorio en el que guardó el archivo AppDomainUnloadAll.vbs. Ejecute el script escribiendo lo siguiente en la ventana del símbolo del sistema que acaba de abrir:

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

Como alternativa a la sintaxis de consulta WQL, puede usar el método InstancesOf de WMI, como hizo anteriormente con WorkerProcess:

Set oAppDomains = oWebAdmin.InstancesOf("AppDomain")

Enumeración de AppDomains

Puede mostrar todos los AppDomains que se ejecutan actualmente y sus propiedades mediante un enfoque similar al de los scripts anteriores. Esta es una lista de propiedades de AppDomain:

  • ApplicationPath
  • Identificador
  • IsIdle
  • PhysicalPath
  • ProcessId
  • SiteName

En el script siguiente se muestran todas las propiedades de cada AppDomain excepto la propiedad Physical Path, pero puede agregarla fácilmente. Para mayor comodidad, el script muestra las propiedades clave y en tiempo de ejecución por separado.

Copie el código en el Bloc de notas y guarde el archivo con el nombre AppDomainProps.vbs. Abra una ventana del símbolo del sistema con privilegios elevados y vaya al directorio en el que guardó el archivo AppDomainProps.vbs. Ejecute el script escribiendo lo siguiente en la ventana del símbolo del sistema que acaba de abrir:

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

Salida de ejemplo

El resultado debería tener la siguiente apariencia:

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

Conclusión

En este artículo se han mostrado algunas técnicas básicas de scripting de WMI para recuperar información sobre los procesos de trabajo de IIS y AppDomains. El método InstanceOf de WMI y las consultas WQL se usaron para recuperarlos. Esta es una breve revisión de las tareas presentadas y los métodos que se usaron:

  • Visualización de las solicitudes que se están ejecutando actualmente para un proceso de trabajo: WorkerProcess.GetExecutingRequests
  • Obtención del estado de todos los procesos de trabajo: WorkerProcess.GetState
  • Descarga de un AppDomain específico o todos los AppDomains: AppDomain.Unload