Condividi tramite


Ricezione di un evento WMI

WMI contiene un'infrastruttura di eventi che genera notifiche sulle modifiche apportate ai dati e ai servizi WMI. Le classi di evento wmi forniscono notifiche quando si verificano eventi specifici.

Le sezioni seguenti sono descritte in questo argomento:

Query di eventi

È possibile creare una query semisincrona o asincrona per monitorare le modifiche apportate ai registri eventi, alla creazione di processi, allo stato del servizio, alla disponibilità del computer o allo spazio disponibile su disco e ad altre entità o eventi. Nello scripting viene utilizzato il metodo SWbemServices.ExecNotificationQuery per sottoscrivere gli eventi. In C++, viene usato IWbemServices::ExecNotificationQuery. Per ulteriori informazioni, consultare Chiamata di un metodo.

La notifica di una modifica nel modello di dati WMI standard viene chiamata evento intrinseco . __InstanceCreationEvent o __NamespaceDeletionEvent sono esempi di eventi intrinseci. La notifica di una modifica che un provider effettua per definire un evento del provider è chiamata evento estrinseco. Ad esempio, il provider del Registro di sistema , il provider di risparmio energia , e il provider Win32 definiscono i propri eventi. Per altre informazioni, vedere Determinare il tipo di evento da ricevere.

Esempio

L'esempio seguente di codice di script è una query per l'evento intrinseco __InstanceCreationEvent della classe di evento Win32_NTLogEvent. È possibile eseguire questo programma in background e, quando si verifica un evento, viene visualizzato un messaggio. Se si chiude la finestra di dialogo Attesa di eventi, il programma smette di attendere gli eventi. Ricorda che la SeSecurityPrivilege deve essere abilitata.

Sub SINK_OnObjectReady(objObject, objAsyncContext)
    WScript.Echo (objObject.TargetInstance.Message)
End Sub

Set objWMIServices = GetObject( _
    "WinMgmts:{impersonationLevel=impersonate, (security)}") 

' Create the event sink object that receives the events
Set sink = WScript.CreateObject("WbemScripting.SWbemSink","SINK_")
 
' Set up the event selection. SINK_OnObjectReady is called when
' a Win32_NTLogEvent event occurs
objWMIServices.ExecNotificationQueryAsync sink,"SELECT * FROM __InstanceCreationEvent " & "WHERE TargetInstance ISA 'Win32_NTLogEvent' "

WScript.Echo "Waiting for events"

# Define event Query
$query = "SELECT * FROM __InstanceCreationEvent 
          WHERE TargetInstance ISA 'Win32_NTLogEvent' "

<# Register for event - also specify an action that
displays the log event when the event fires.#>

Register-WmiEvent -Source Demo1 -Query $query -Action {
                Write-Host "Log Event occured"
                $global:myevent = $event
                Write-Host "EVENT MESSAGE"
                Write-Host $event.SourceEventArgs.NewEvent.TargetInstance.Message}
<# So wait #>
"Waiting for events"

Nell'esempio di codice VBScript seguente viene illustrato l'evento estrinsico __RegistryValueChangeEvent definito dal provider del Registro di sistema. Lo script crea un consumer temporaneo usando la chiamata a SWbemServices.ExecNotificationQueryAsynce riceve solo eventi quando lo script è in esecuzione. Lo script seguente viene eseguito a tempo indeterminato fino a quando il computer non viene riavviato, WMI viene arrestato o lo script viene arrestato. Per arrestare manualmente lo script, usare Gestione attività per arrestare il processo. Per arrestarla a livello di codice, usare il metodoTerminatenella classe Win32_Process. Per altre informazioni, vedere Configurazione della sicurezza in una chiamata asincrona.

strComputer = "."

Set objWMIServices=GetObject( _
    "winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default")

set objSink = WScript.CreateObject("WbemScripting.SWbemSink","SINK_")


objWMIServices.ExecNotificationQueryAsync objSink, _
    "Select * from RegistryValueChangeEvent Where Hive = 'HKEY_LOCAL_MACHINE' and KeyPath = 'SYSTEM\\ControlSet001\\Control' and ValueName = 'CurrentUser'"

WScript.Echo "Waiting for events..."

While (True) 
     WScript.Sleep (1000)
Wend

 
WScript.Echo "Listening for Registry Change Events..." & vbCrLf 

While(True) 
    WScript.Sleep 1000 
Wend 

Sub SINK_OnObjectReady(wmiObject, wmiAsyncContext) 
    WScript.Echo "Received Registry Value Change Event" & vbCrLf & wmiObject.GetObjectText_() 
End Sub

Consumer di eventi

È possibile monitorare o utilizzare eventi usando i consumer seguenti durante l'esecuzione di uno script o di un'applicazione:

  • Consumatori di eventi temporanei

    Un consumer temporaneo è un'applicazione client WMI che riceve un evento WMI. WMI include un'interfaccia univoca che WMI usa per specificare gli eventi da inviare a un'applicazione client. Un consumer di eventi temporanei viene considerato temporaneo perché funziona solo quando viene caricato in modo specifico da un utente. Per altre informazioni, vedere Ricezione di Eventi per la Durata dell'Applicazione.

  • Consumatori di eventi permanenti

    Un consumer permanente è un oggetto COM che può ricevere un evento WMI in qualsiasi momento. Un consumatore permanente di eventi utilizza un insieme di oggetti persistenti e filtri per acquisire un evento di WMI. Come un consumer di eventi temporanei, è possibile impostare una serie di oggetti WMI e filtri che acquisiscono un evento WMI. Quando si verifica un evento che corrisponde a un filtro, WMI carica il gestore di eventi permanente e lo informa dell'evento. Poiché un consumer permanente viene implementato nel repository WMI ed è un file eseguibile registrato in WMI, il consumer di eventi permanente opera e riceve gli eventi dopo la creazione e anche dopo un riavvio del sistema operativo, purché WMI sia in esecuzione. Per altre informazioni, vedere ricezione di eventi in qualsiasi momento.

Gli script o le applicazioni che ricevono eventi hanno particolari considerazioni sulla sicurezza. Per ulteriori informazioni, consultare Protezione degli eventi WMI.

Un'applicazione o uno script può usare un provider di eventi WMI predefinito che fornisce classi consumatore standard. Ogni classe consumer standard risponde a un evento con un'azione diversa inviando un messaggio di posta elettronica o eseguendo uno script. Non è necessario scrivere codice del fornitore per usare una classe consumatore standard per creare un consumatore di eventi permanente. Per ulteriori informazioni, vedere Monitoraggio e risposta agli eventi con consumatori standard.

Fornitura di eventi

Un provider di eventi è un componente COM che invia un evento a WMI. È possibile creare un provider di eventi per inviare un evento in un'applicazione C++ o C#. La maggior parte dei provider di eventi gestisce un oggetto per WMI, ad esempio un'applicazione o un elemento hardware. Per ulteriori informazioni, vedere Creazione di un provider di eventi.

Un evento temporizzato o ripetuto è un evento che si verifica in un momento predeterminato.

WMI offre i modi seguenti per creare eventi temporali o ripetuti per le applicazioni:

  • Infrastruttura di eventi Microsoft standard.
  • Classe timer specializzata.

Per ulteriori informazioni, vedere ricezione di un evento programmato o ricorrente. Quando scrivete un provider di eventi, considerate le informazioni di sicurezza identificate in Fornire Eventi in Modo Sicuro.

È consigliabile compilare sottoscrizioni di eventi permanenti nello spazio dei nomi oot\subscription \r. Per ulteriori informazioni, consultare Implementazione delle sottoscrizioni permanenti agli eventi tra namespace.

Quote di sottoscrizione

Il polling degli eventi può degradare le prestazioni per i provider che supportano query su set di dati molto ampi. Inoltre, qualsiasi utente con accesso in lettura a uno spazio dei nomi con provider dinamici può tentare un attacco di tipo Denial of Service (DoS). WMI mantiene le quote combinate per tutti gli utenti e per ogni consumer di eventi nella singola istanza di __ArbitratorConfiguration situata nello spazio dei nomi \root. Queste quote sono globali anziché per ogni spazio dei nomi. Non è possibile modificare le quote.

WMI applica attualmente quote usando le proprietà di __ArbitratorConfiguration. Ogni quota ha un valore per utente e una versione totale che comprende la somma di tutti gli utenti, non per spazio dei nomi. Nella tabella seguente sono elencate le quote applicabili alle proprietà __ArbitratorConfiguration.

Totale/Per Utente Quota
TotaleAbbonamentiTemporanei
SottoscrizioniTemporaneePerUtente
10.000
1,000
Totale abbonamenti permanenti
AbbonamentiPermanentiPerUtente
10.000
1,000
IstruzioniTotaliDiVoto
Istruzioni di Votazione per Utente
10.000
1,000
MemoriaTotaleSondaggio
MemoriaDiSondaggioPerUtente
10.000.000 (0x989680) byte
5.000.000 byte (0x4CB40)

Un amministratore o un utente con autorizzazione FULL_WRITE nello spazio dei nomi può modificare l'istanza singleton di __ArbitratorConfiguration. WMI tiene traccia della quota per utente.

L'uso di WMI