Share via


Gestione di processi di lavoro e AppDomains in IIS 7 con WMI

di Tim Ammann

Lo script WMI consente di gestire i processi di lavoro e i domini dell'applicazione (AppDomains) in IIS con facilità relativa. I processi di lavoro IIS vengono generati dal servizio di attivazione dei processi di Windows (WAS) ed eseguiti da W3wp.exe. I processi di lavoro possono contenere AppDomains che vengono in genere creati in risposta a una richiesta per una pagina con estensione aspx.

Questo articolo descrive come eseguire, con poche righe di VBScript, le attività seguenti:

  • Visualizzare le richieste attualmente in esecuzione per un processo di lavoro
  • Ottenere lo stato di tutti i processi di lavoro
  • Scaricare un appDomain specifico o tutti i Domini app
  • Visualizzare tutti i domini app e le relative proprietà

Primi passaggi

  1. Assicurarsi che IIS e scripting siano abilitati.

    a. Se si usa Windows Vista, aprire Pannello di controllo, Programmi e funzionalità e quindi Funzionalità di Windows. In "Strumenti di gestione Web" selezionare "Script e strumenti di gestione IIS" per abilitare lo scripting. b. Se si usa Windows Server® 2008, aprire Server Manager. Usare la Procedura guidata Aggiungi ruoli per installare il server Web IIS. Nella sezione Strumenti di gestione della pagina Seleziona servizi ruolo selezionare "Script e strumenti di gestione IIS".

  2. Eseguire comandi come amministratore. Per aprire una finestra del prompt dei comandi con privilegi elevati, fare clic sul pulsante Start, scegliere Tutti i programmi, Accessori, fare clic con il pulsante destro del mouse su Prompt dei comandi, quindi scegliere Esegui come amministratore. Se si apre una shell dei comandi come amministratore, tutte le applicazioni eseguite dalla shell dei comandi verranno eseguite come amministratore.

  3. Salvare i file di script in formato di testo con estensione vbs. Possono essere eseguiti al prompt dei comandi usando la sintassi "cscript.exe <nome script.vbs>".

  4. Prima di iniziare, eseguire un backup del file System32\inetsrv\config\applicationhost.config con lo strumento AppCmd. La copia di backup consente di ripristinare IIS allo stato originale copiando la versione originale su quella successiva. Per eseguire un backup, seguire questa procedura:

    a. Aprire una finestra del prompt dei comandi con privilegi elevati
    b. Digitare cd %Windir%\system32\inetsrv\ c.Type appcmd aggiungere backup backupName per eseguire il backup del file ApplicationHost.config, dove backupName è il nome specificato per il backup. Una directory con il nome di backup specificato verrà creata nella %Windir%\system32\inetsrv\backup directory. Se non si specifica un nome, appcmd genera automaticamente un nome per la directory utilizzando la data e l'ora correnti.

Processi di lavoro

Questa sezione illustra come recuperare le richieste attualmente in esecuzione per ogni processo di lavoro in un server Web. Si apprenderà quindi come visualizzare il piD, lo stato e il pool di applicazioni a cui appartiene ogni processo di lavoro.

Ottenere richieste di esecuzione

Una nuova funzionalità interessante di IIS è la possibilità di visualizzare le richieste attualmente in esecuzione in un processo di lavoro. È possibile eseguire questa operazione con il metodo WorkerProcess.GetExecutingRequests.

Il metodo WorkerProcess.GetExecutingRequests segnala in modo snapshot le richieste eseguite al momento dell'esecuzione del metodo. Poiché la maggior parte delle richieste viene eseguita molto rapidamente, potrebbe non essere facile testare manualmente il metodo con un Web browser. Per questo motivo, si creerà una pagina Web solo per questo scopo.

Usare il blocco note per inserire il testo seguente in un file di testo. Salvare quindi il file usando il nome Sleep.aspx.

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

Inserire il file Sleep.aspx nella directory del contenuto del sito Web predefinito: %systemdrive%\inetpub\wwwroot.

Il file Sleep.aspx creato forza l'esecuzione della richiesta per la pagina Web per l'esecuzione di 30 secondi. In questo modo sarà possibile eseguire uno script che mostrerà GetExecutingRequests in azione.

Il metodo GetExecutingRequests accetta una variabile di matrice vuota come parametro OUT, che quindi riempie con oggetti HttpRequest. È possibile eseguire l'iterazione di queste richieste per visualizzare gli attributi per ogni richiesta. Lo script seguente accetta l'output dell'oggetto HttpRequest e visualizza il modulo corrente, il verbo, il nome host e l'URL per ogni richiesta.

Copiare lo script seguente nel blocco note e salvarlo con il nome file 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

Aprire una finestra del prompt dei comandi con privilegi elevati e passare alla directory in cui è stato salvato il file di GetRequests.vbs.

Prima di eseguire lo script, digitare http://localhost/sleep.aspx nella barra degli indirizzi di un Web browser. Verrà avviata l'esecuzione della richiesta e verrà impostato il browser in rotazione per 30 secondi mentre attende di eseguire il rendering della pagina Sleep.aspx.

Mentre il browser è ancora in attesa di eseguire il rendering della pagina, eseguire lo script digitando quanto segue nella finestra del prompt dei comandi appena aperta:

Cscript.exe GetRequests.vbs

Output di esempio

L'output visualizzato dovrebbe essere simile al seguente.

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

Recupero dello stato di un processo di lavoro

L'oggetto WorkerProcess nel provider WMI IIS ha un metodo GetState che rivela se un processo di lavoro viene avviato, in esecuzione o arrestato. WorkerProcess include anche due proprietà che ci interessano qui: ApplicationPool e PID. La proprietà ApplicationPool rappresenta il pool di applicazioni a cui appartiene il processo di lavoro. La proprietà PID contiene l'ID processo che identifica in modo univoco il processo di lavoro.

È possibile usare il codice seguente per elencare ogni processo di lavoro PID e stato e il relativo pool di applicazioni. Se non vengono eseguiti processi di lavoro, lo script verrà chiuso in modo invisibile all'utente. Copiare il codice nel blocco note e salvarlo con il nome file 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

Aprire una finestra del prompt dei comandi con privilegi elevati e passare alla directory in cui è stato salvato il file di GetState.vbs. Eseguire lo script digitando quanto segue nella finestra del prompt dei comandi appena aperta:

Cscript.exe GetState.vbs

Output di esempio

L'output dovrebbe essere simile al seguente:

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

Dopo aver appreso di usare script WMI per rivelare i segreti dei processi di lavoro, eseguire la stessa operazione per i domini dell'applicazione.

AppDomain

La prima volta che viene ricevuta una richiesta per una pagina ASP.NET, il modulo del motore gestito IIS crea un dominio applicazione (AppDomain) in memoria. AppDomain elabora le richieste per le pagine aspx o qualsiasi pagina che usa codice gestito. Scaricare ed enumerare AppDomains usando WMI è semplice e questa sezione illustra come eseguire entrambe le operazioni.

Scaricare un appDomain specifico

Lo scarico di AppDomain in IIS 7 e versioni successive funziona in modo leggermente diverso rispetto a IIS 6.0. Mentre il comando IIS 6.0 AppUnload non caricato applicazioni ASP non elaborate, il metodo IIS 7 e versioni successive di AppDomain.Unload scarica solo ASP.NET domini applicazione. La funzionalità AppUnload è scomparsa perché la modalità di compatibilità IIS 5.0 supportata non è più presente in IIS 7 e versioni successive.

Per scaricare un AppDomain specifico, è necessario essere in grado di identificarlo in modo univoco. Gli oggetti AppDomain hanno tre proprietà chiave: ApplicationPath, ID e SiteName. Tuttavia, solo uno di questi può essere sufficiente per i tuoi scopi.

Tra l'altro, la proprietà ID AppDomain non è un numero, ma un percorso simile al seguente:

/LM/W3SVC/1/ROOT

Il valore "1" nel percorso elencato è l'ID sito (per impostazione predefinita, 1 corrisponde al sito Web predefinito). Se è necessario generare un elenco dei domini app del server e delle relative proprietà, vedere la sezione "Enumerazione di AppDomains" più avanti in questo articolo.

Lo script successivo scarica l'AppDomain denominato "Northwind". Lo script esegue l'iterazione tramite appDomains disponibili finché non trova quello con ApplicationPath corrispondente. Copiare il codice nel blocco note, sostituire "Northwind" con il percorso dell'applicazione AppDomain desiderato e salvare il file con il nome AppDomainUnload.vbs.

Aprire una finestra del prompt dei comandi con privilegi elevati e passare alla directory in cui è stato salvato il file di AppDomainUnload.vbs. Eseguire lo script digitando quanto segue nella finestra del prompt dei comandi appena aperta:

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

Scaricare tutti i domini app

Scaricare tutti i Domini app in un server è ancora più semplice: è sufficiente recuperarli, eseguirne l'iterazione e scaricare ognuno a sua volta.

L'esempio seguente scarica tutti i domini applicazione in un server Web IIS. Si noti come viene usata una semplice query WQL (WQL è la versione di SQL) per recuperare AppDomains.

Copiare il codice nel blocco note e salvare il file con il nome AppDomainUnloadAll.vbs. Aprire una finestra del prompt dei comandi con privilegi elevati e passare alla directory in cui è stato salvato il file di AppDomainUnloadAll.vbs. Eseguire lo script digitando quanto segue nella finestra del prompt dei comandi appena aperta:

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

In alternativa alla sintassi della query WQL, è possibile usare il metodo ISTANZE WMIOf, come illustrato in precedenza con WorkerProcess:

Set oAppDomains = oWebAdmin.InstancesOf("AppDomain")

Enumerazione di AppDomains

È possibile visualizzare tutte le proprietà attualmente in esecuzione di AppDomain e le relative proprietà usando un approccio simile a quello degli script precedenti. Ecco un elenco delle proprietà di AppDomain:

  • ApplicationPath
  • ID
  • IsIdle
  • PhysicalPath
  • ProcessId
  • SiteName

Lo script seguente mostra tutte le proprietà per ogni AppDomain, ad eccezione della proprietà Physical Path, ma è possibile aggiungerla con facilità. Per praticità, lo script visualizza separatamente le proprietà della chiave e della fase di esecuzione.

Copiare il codice nel Blocco note e salvare il file con il nome AppDomainProps.vbs. Aprire una finestra del prompt dei comandi con privilegi elevati e passare alla directory in cui è stato salvato il file AppDomainProps.vbs. Eseguire lo script digitando quanto segue nella finestra del prompt dei comandi appena aperta:

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

Output di esempio

L'output sarà simile al seguente:

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

Conclusione

Questo articolo ha illustrato alcune tecniche di scripting WMI di base per il recupero di informazioni sui processi di lavoro IIS e su AppDomain. Il metodo InstanceOf WMI e le query WQL sono stati usati per recuperarli. Ecco una breve revisione delle attività presentate e dei metodi usati:

  • Visualizzare le richieste attualmente in esecuzione per un processo di lavoro: WorkerProcess.GetExecutingRequests
  • Ottenere lo stato di tutti i processi di lavoro: WorkerProcess.GetState
  • Scaricare un AppDomain specifico o tutti i Domini app: AppDomain.Unload