Управление рабочими процессами и доменами приложений в IIS 7 с помощью инструментария WMI

Тим Амманн (Tim Ammann)

Использование скриптов WMI позволяет относительно легко управлять рабочими процессами и доменами приложений (доменами приложений) в IIS. Рабочие процессы IIS создаются службой активации процессов Windows (WAS) и выполняются W3wp.exe. Рабочие процессы могут содержать домены приложений, которые обычно создаются в ответ на запрос aspx-страницы.

В этой статье описано, как выполнить следующие задачи с помощью нескольких строк VBScript:

  • Просмотр текущих выполняемых запросов для рабочего процесса
  • Получение состояния всех рабочих процессов
  • Выгрузка определенного домена приложения или всех доменов приложений
  • Отображение всех доменов приложений и их свойств

Первые шаги

  1. Убедитесь, что службы IIS и скрипты включены.

    а. Если вы используете Windows Vista, откройте панель управления, Программы и компоненты, а затем Компоненты Windows. В разделе "Средства управления веб-сайтами" выберите "Сценарии и средства управления IIS", чтобы включить скрипты. b. Если вы используете Windows Server® 2008, откройте диспетчер сервера. Используйте мастер добавления ролей, чтобы установить веб-сервер IIS. На странице Выбор служб ролей в разделе Средства управления выберите "Сценарии и средства управления IIS".

  2. Выполните команды от имени администратора. Чтобы открыть окно командной строки с повышенными правами, нажмите кнопку Пуск, подведите указатель к пункту Все программы, выберите пункт Стандартные, щелкните правой кнопкой мыши пункт Командная строка и выберите пункт Запуск от имени администратора. Если открыть командную оболочку от имени администратора, все приложения, запускаемые из этой командной оболочки, будут выполняться от имени администратора.

  3. Сохраните файлы скриптов в текстовом формате с расширением VBS. Их можно запустить в командной строке с помощью синтаксиса "cscript.exe <scriptname.vbs>".

  4. Перед началом работы создайте резервную копию файла System32\inetsrv\config\applicationhost.config с помощью средства AppCmd. Резервная копия позволит восстановить исходное состояние служб IIS, просто скопировав исходную версию более поздней. Чтобы создать резервную копию, выполните следующие действия.

    а. Откройте окно командной строки с повышенными правами.
    b. Введите cd %Windir%\system32\inetsrv\ c.Type appcmd add backupName для резервного копирования файла ApplicationHost.config, где backupName — это имя, указанное для резервной копии. В каталоге будет создан каталог с указанным именем резервной %Windir%\system32\inetsrv\backup копии. Если имя не указано, appcmd автоматически создаст имя каталога с использованием текущей даты и времени.

Рабочие процессы

В этом разделе показано, как получить текущие выполняемые запросы для каждого рабочего процесса на веб-сервере. Затем вы узнаете, как отобразить PID каждого рабочего процесса, состояние и пул приложений, к которому он принадлежит.

Получение выполняемых запросов

Одной из интересных новых возможностей IIS является возможность просматривать запросы, которые в настоящее время выполняются в рабочем процессе. Это можно сделать с помощью метода WorkerProcess.GetExecutingRequests.

Метод WorkerProcess.GetExecutingRequests передает моментальный снимок запросов, которые выполнялись во время выполнения метода. Так как большинство запросов выполняются очень быстро, вам может быть непросто протестировать метод вручную в веб-браузере. По этой причине вы создадите веб-страницу только для этой цели.

Используйте Блокнот, чтобы поместить следующий текст в текстовый файл. Затем сохраните файл с именем Sleep.aspx.

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

Поместите файл Sleep.aspx в каталог содержимого веб-сайта по умолчанию: %systemdrive%\inetpub\wwwroot.

Созданный файл Sleep.aspx приводит к тому, что запрос веб-страницы выполняется в течение 30 секунд. Это даст вам время для выполнения скрипта, который будет отображать GetExecutingRequests в действии.

Метод GetExecutingRequests принимает пустую переменную массива в качестве параметра OUT, который затем заполняется объектами 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.

Перед запуском скрипта введите http://localhost/sleep.aspx в адресной строке веб-браузера. Это запустит выполнение запроса и задаст браузер в течение 30 секунд, пока он ожидает отрисовки страницы Sleep.aspx.

Пока браузер все еще ожидает отрисовки страницы, запустите сценарий, введя следующую команду в открывшемся окне командной строки:

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]

Получение состояния рабочего процесса

Объект WorkerProcess в поставщике WMI IIS имеет метод GetState, который показывает, запускается или останавливается рабочий процесс. WorkerProcess также имеет два свойства, которые интересуют нас здесь: ApplicationPool и PID. Свойство ApplicationPool представляет пул приложений, к которому принадлежит рабочий процесс. Свойство PID содержит идентификатор процесса, который однозначно идентифицирует рабочий процесс.

Вы можете использовать следующий код для перечисления 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 создает домен приложения (AppDomain) в памяти. AppDomain обрабатывает запросы aspx-страниц или любой страницы, которая использует управляемый код. Выгрузка и перечисление доменов приложений с помощью инструментария WMI выполняется легко, и в этом разделе показано, как это сделать.

Выгрузка определенного домена приложения

Выгрузка домена приложения в IIS 7 и более поздних версиях работает несколько иначе, чем в IIS 6.0. В то время как команда AppUnload iis 6.0 выгружает внепроцессные приложения ASP, метод IIS 7 и более поздних версий AppDomain.Unload выгружает только ASP.NET доменов приложений. Функциональность AppUnload исчезла, так как поддерживаемый режим совместимости IIS 5.0 больше не присутствует в IIS 7 и более поздних версиях.

Чтобы выгрузить определенный appDomain, необходимо иметь возможность однозначно идентифицировать его. Объекты AppDomain имеют три ключевых свойства: ApplicationPath, ID и SiteName. Однако только одного из них может быть достаточно для ваших целей.

Кстати, свойство AppDomain ID — это не число, а путь, который выглядит следующим образом:

/LM/W3SVC/1/ROOT

1 в указанном пути — это идентификатор сайта (по умолчанию 1 соответствует веб-сайту по умолчанию). Если необходимо сначала создать список доменов приложений сервера и их свойств, см. раздел "Перечисление доменов приложений" далее в этой статье.

Следующий скрипт выгружает домен приложения с именем "Northwind". Скрипт выполняет итерацию по доступным доменам AppDomain, пока не найдет тот, с соответствующим ApplicationPath. Скопируйте код в Блокнот, замените "Northwind" выбранным путем приложения AppDomain и сохраните файл с именем 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. Обратите внимание, что для получения доменов приложений используется простой запрос 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, как и ранее с WorkerProcess:

Set oAppDomains = oWebAdmin.InstancesOf("AppDomain")

Перечисление доменов приложений

Вы можете отобразить все текущие домены приложений и их свойства, используя подход, аналогичный предыдущему скрипту. Ниже приведен список свойств AppDomain:

  • ApplicationPath
  • Идентификатор
  • IsIdle
  • PhysicalPath
  • ProcessId
  • SiteName

Следующий скрипт показывает все свойства для каждого домена Приложения, кроме свойства Физический путь, но вы можете добавить его достаточно легко. Для удобства скрипт отображает ключ и свойства времени выполнения отдельно.

Скопируйте код в Блокнот и сохраните файл с именем 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

Заключение

В этой статье описаны некоторые основные методы создания скриптов WMI для получения сведений о рабочих процессах IIS и доменах приложений. Для их извлечения использовались метод WMI InstanceOf и WQL-запросы. Ниже приведен краткий обзор представленных задач и используемых методов.

  • Просмотр текущих выполняемых запросов для рабочего процесса: WorkerProcess.GetExecutingRequests
  • Получение состояния всех рабочих процессов: WorkerProcess.GetState
  • Выгрузка определенного домена приложения или всех доменов приложений: AppDomain.Unload