Gestion des processus de travail et des AppDomain dans IIS 7 avec WMI

Auteur Tim Ammann

Le script WMI vous permet de gérer les processus de travail et les domaines d'application (AppDomains) dans IIS avec une facilité relative. Les processus de travail IIS sont générés par le service d'activation de processus Windows (WAS) et exécutés par W3wp.exe. Les processus de travail peuvent contenir des AppDomains qui sont généralement créés en réponse à une demande de page .aspx.

Cet article explique comment accomplir les tâches suivantes, avec seulement quelques lignes de VBScript :

  • Afficher les demandes en cours d'exécution d'un processus de travail
  • Obtenir l'état de tous les processus de travail
  • Décharger un AppDomain spécifique ou tous les Domaines d'application
  • Afficher tous les AppDomains et leurs propriétés

Premières étapes

  1. Vérifiez que IIS et les scripts sont activés.

    a. Si vous utilisez Windows Vista, ouvrez panneau de configuration, programmes et fonctionnalités, puis fonctionnalités Windows. Sous « Outils de gestion web », sélectionnez « Scripts et outils de gestion IIS » pour activer le script. b. Si vous utilisez Windows Server® 2008, ouvrez le Gestionnaire de serveur. Utilisez l'Assistant Ajouter des rôles pour installer le serveur Web IIS. Dans la page Sélectionner les services de rôle, dans la section Outils de gestion, sélectionnez « Scripts et outils de gestion IIS ».

  2. Exécutez les commandes en tant qu'administrateur. Pour ouvrir une fenêtre d’invite de commandes avec élévation de privilèges, pointez sur Démarrer, Tous les programmes, cliquez sur Accessoires, cliquez avec le bouton droit sur Invite de commandes, puis cliquez sur Exécuter en tant qu’administrateur. Si vous ouvrez un interpréteur de commandes en tant qu'administrateur, toutes les applications que vous exécutez à partir de cet interpréteur de commandes s'exécutent en tant qu'administrateur.

  3. Enregistrez les fichiers de script au format texte avec une extension .vbs. Ils peuvent être exécutés à l'invite de commandes à l'aide de la syntaxe « cscript.exe <scriptname>.vbs ».

  4. Avant de commencer, effectuez une sauvegarde du fichier System32\inetsrv\config\applicationhost.config avec l'outil AppCmd. La copie de sauvegarde vous permet de restaurer IIS à son état d'origine en copiant simplement la version d'origine sur la version ultérieure. Pour effectuer une sauvegarde, procédez comme suit :

    a. Ouvrez une fenêtre d'invite de commandes avec privilèges élevés.
    b. Tapez cd %Windir%\system32\inetsrv\c.Tapez appcmd add backup backupName pour sauvegarder le fichier ApplicationHost.config, où backupName est le nom que vous spécifiez pour la sauvegarde. Un répertoire avec le nom de sauvegarde que vous spécifiez sera créé sous le répertoire %Windir%\system32\inetsrv\backup. Si vous ne spécifiez pas de nom, appcmd génère automatiquement un nom de répertoire à l'aide de la date et de l'heure actuelles.

Processus de travail

Cette section vous montre comment récupérer les demandes en cours d'exécution pour chaque processus de travail sur un serveur web. Vous allez ensuite apprendre à afficher le PID, l'état et le pool d'applications auxquels il appartient.

Accéder aux demandes d'exécution

L'une des nouvelles fonctionnalités intéressantes d'IIS est la possibilité de consulter les requêtes en cours d'exécution dans un processus de travail. Pour ce faire, utilisez la méthode WorkerProcess.GetExecutingRequests.

La méthode WorkerProcess.GetExecutingRequests signale de manière instantanée les requêtes qui s'exécutaient au moment de l'exécution de la méthode. Étant donné que la plupart des requêtes s'exécutent très rapidement, il peut ne pas être facile de tester la méthode manuellement avec un navigateur Web. C'est pourquoi vous créerez une page Web à cet effet.

Utilisez le bloc-notes pour placer le texte suivant dans un fichier texte. Ensuite, enregistrez le fichier à l'aide du nom Sleep.aspx.

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

Placez le fichier Sleep.aspx dans le répertoire de contenu du site Web par défaut : %systemdrive%\inetpub\wwwroot.

Le fichier Sleep.aspx que vous avez créé force l'exécution de la requête pour que la page Web prenne 30 secondes. Cela vous donnera le temps d'exécuter un script qui affichera GetExecutingRequests en action.

La méthode GetExecutingRequests accepte une variable de tableau vide en tant que paramètre OUT, qu'elle remplit ensuite avec des objets HttpRequest. Vous pouvez itérer au sein de ces requêtes pour afficher les attributs de chaque requête. Le script suivant prend la sortie de l'objet HttpRequest et affiche le module actuel, le verbe, le nom d'hôte et l'URL de chaque requête.

Copiez le script suivant dans le Bloc-notes et enregistrez-le avec le nom de fichier 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

Ouvrez une fenêtre d'invite de commandes avec élévation de privilèges, et accédez au répertoire dans lequel vous avez enregistré le fichier GetRequests.vbs.

Avant d'exécuter le script, tapez http://localhost/sleep.aspx dans la barre d'adresse d'un navigateur Web. Cela lancera l'exécution de la demande et fera tourner le navigateur pendant 30 secondes en attendant l'affichage de la page Sleep.aspx.

Pendant que le navigateur attend toujours l'affichage de la page, exécutez le script en tapant ce qui suit dans la fenêtre d'invite de commandes que vous venez d'ouvrir :

Cscript.exe GetRequests.vbs

Exemple de sortie

La sortie que vous voyez doit ressembler à ce qui suit.

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

Obtention de l'état d'un processus de travail

L'objet WorkerProcess dans le fournisseur WMI IIS a une méthode GetState qui indique si un processus de travail démarre, s'exécute ou s'arrête. WorkerProcess possède également deux propriétés qui nous intéressent ici : ApplicationPool et PID. La propriété ApplicationPool représente le pool d'applications auquel appartient le processus de travail. La propriété PID contient l'ID de processus qui identifie de façon unique le processus de travail.

Vous pouvez utiliser le code suivant pour répertorier chaque PID et état du processus worker, ainsi que son pool d'applications. Si aucun processus de travail n'est en cours d'exécution, le script s'arrête en mode silencieux. Copiez le code dans le Bloc-notes et enregistrez-le avec le nom de fichier 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

Ouvrez une fenêtre d'invite de commandes avec élévation de privilèges et accédez au répertoire dans lequel vous avez enregistré le fichier GetState.vbs. Exécutez le script en tapant ce qui suit dans la fenêtre d'invite de commandes que vous venez d'ouvrir :

Cscript.exe GetState.vbs

Exemple de sortie

La sortie doit ressembler à ceci :

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

Maintenant que vous avez appris à utiliser des scripts WMI pour révéler les secrets des processus de travail, procédez de la même façon pour les domaines d'application.

AppDomains

La première fois qu'une demande d'une page ASP.NET est reçue, le module du moteur managé IIS crée un domaine d'application (AppDomain) en mémoire. AppDomain traite les demandes de pages aspx, ou toute page qui utilise du code managé. Il est facile de décharger et d'énumérer les AppDomains en utilisant WMI. À cet effet, cette section vous montre comment faire les deux.

Déchargement d'un AppDomain spécifique

Le déchargement AppDomain dans IIS 7 et versions ultérieures fonctionne un peu différemment de celui d'IIS 6.0. Alors que la commande AppUnload d'IIS 6.0 déchargeait les applications ASP hors processus, la méthode AppDomain.Unload d'IIS 7 et des versions ultérieures décharge uniquement les domaines d'application ASP.NET. La fonctionnalité AppUnload a disparu, car le mode de compatibilité IIS 5.0 pris en charge n'est plus présent dans IIS 7 et versions ultérieures.

Pour décharger un AppDomain spécifique, vous devez être en mesure de l'identifier de manière unique. Les objets AppDomain ont trois propriétés clés : ApplicationPath, ID et SiteName. Toutefois, l'un d'entre eux peut suffire à vos besoins.

Par ailleurs, la propriété AppDomain ID n'est pas un nombre, mais un chemin qui ressemble à ceci :

/LM/W3SVC/1/ROOT

Le « 1 » dans le chemin répertorié est l'ID de site (par défaut, 1 correspond au site web par défaut.) Si vous devez d'abord générer une liste des AppDomains de votre serveur et de leurs propriétés, consultez, plus loin dans cet article, la section « Énumération d'AppDomains ».

Le script suivant décharge l'AppDomain appelé « Northwind ». Le script effectue une itération via les AppDomains disponibles jusqu'à ce qu'il trouve celui qui correspond à ApplicationPath. Copiez le code dans le Bloc-notes, remplacez « Northwind » par le chemin d'accès de l'application AppDomain de votre choix, puis enregistrez le fichier avec le nom AppDomainUnload.vbs.

Ouvrez une fenêtre d'invite de commandes avec élévation de privilèges, et accédez au répertoire dans lequel vous avez enregistré le fichier AppDomainUnload.vbs. Exécutez le script en tapant ce qui suit dans la fenêtre d'invite de commandes que vous venez d'ouvrir :

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

Déchargement de tous les appDomains

Il est encore plus facile de décharger tous les AppDomains d'un serveur : il suffit de les récupérer, de les parcourir et de les décharger l'un après l'autre.

L'exemple suivant décharge tous les domaines d'application sur un serveur web IIS. Notez comment une requête WQL simple (WQL est la version de WMI de SQL) est utilisée pour récupérer les AppDomains.

Copiez le code dans le Bloc-notes, et enregistrez le fichier avec le nom AppDomainUnloadAll.vbs. Ouvrez une fenêtre d'invite de commandes avec élévation de privilèges et accédez au répertoire dans lequel vous avez enregistré le fichier AppDomainUnloadAll.vbs. Exécutez le script en tapant ce qui suit dans la fenêtre d'invite de commandes que vous venez d'ouvrir :

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

En guise d'alternative à la syntaxe de requête WQL, vous pouvez utiliser la méthode WMI InstancesOf, comme vous l'avez fait précédemment avec WorkerProcess :

Set oAppDomains = oWebAdmin.InstancesOf("AppDomain")

Énumération d'AppDomains

Vous pouvez afficher tous les AppDomains en cours d'exécution et leurs propriétés en utilisant une approche similaire à celle des scripts précédents. Voici la liste des propriétés AppDomain :

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

Le script suivant affiche toutes les propriétés de chaque AppDomain à l'exception de la propriété Physical Path. Cependant, vous pouvez l'ajouter assez facilement. Pour plus de commodité, le script affiche séparément les propriétés de clé et d'exécution.

Copiez le code dans le Bloc-notes et enregistrez le fichier avec le nom AppDomainProps.vbs. Ouvrez une fenêtre d'invite de commandes avec élévation de privilèges et accédez au répertoire dans lequel vous avez enregistré le fichier AppDomainProps.vbs. Exécutez le script en tapant ce qui suit dans la fenêtre d'invite de commandes que vous venez d'ouvrir :

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

Exemple de sortie

Votre sortie doit se présenter comme suit :

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

Conclusion

Cet article a montré des techniques de script WMI de base pour récupérer des informations sur les processus de travail IIS et AppDomains. La méthode WMI InstanceOf et les requêtes WQL ont été utilisées pour les récupérer. Voici un bref aperçu des tâches présentées et des méthodes utilisées :

  • Afficher les demandes en cours d'exécution d'un processus de travail : WorkerProcess.GetExecutingRequests
  • Obtenir l'état de tous les processus de travail : WorkerProcess.GetState
  • Décharger un AppDomain spécifique ou tous les Domaines d'application : AppDomain.Unload