Réception d’un événement WMI

WMI contient une infrastructure d’événements qui génère des notifications sur les changements apportés aux données et services WMI. Les classes d’événements WMI fournissent des notifications quand des événements spécifiques se produisent.

Les sections suivantes sont traitées dans cette rubrique :

Requêtes d’événement

Vous pouvez créer une requête semi-synchrone ou asynchrone pour effectuer le monitoring des changements apportés aux journaux des événements, à la création de processus, à l’état du service, à la disponibilité de l’ordinateur ou à l’espace libre sur le lecteur de disque ainsi qu’à d’autres entités ou événements. Dans les scripts, la méthode SWbemServices.ExecNotificationQuery est utilisée pour s’abonner aux événements. En C++, IWbemServices::ExecNotificationQuery est utilisé. Pour plus d’informations, consultez Appel d’une méthode.

La notification d’un changement dans le modèle de données WMI standard s’appelle un événement intrinsèque. __InstanceCreationEvent ou __NamespaceDeletionEvent sont des exemples d’événements intrinsèques. La notification d’un changement effectué par un fournisseur pour définir un événement de fournisseur s’appelle un événement extrinsèque. Par exemple, le fournisseur de Registre système, le fournisseur d’événements de gestion de l’alimentation et le fournisseur Win32 définissent leurs propres événements. Pour plus d’informations, consultez Détermination du type d’événement à recevoir.

Exemple

L’exemple de code de script suivant est une requête portant sur l’attribut __InstanceCreationEvent intrinsèque de la classe d’événements Win32_NTLogEvent. Vous pouvez exécuter ce programme en arrière-plan. En cas d’événement, un message s’affiche. Si vous fermez la boîte de dialogue En attente d’événements, le programme cesse d’attendre les événements. N’oubliez pas que SeSecurityPrivilege doit être activé.

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"

L’exemple de code VBScript suivant montre l’événement extrinsèque __RegistryValueChangeEvent défini par le fournisseur de Registre. Le script crée un consommateur temporaire via l’appel de SWbemServices.ExecNotificationQueryAsync, et reçoit uniquement les événements quand le script est en cours d’exécution. Le script suivant s’exécute indéfiniment jusqu’à ce que l’ordinateur redémarre, que WMI soit arrêté ou que le script soit arrêté. Pour arrêter le script manuellement, utilisez le Gestionnaire des tâches pour arrêter le processus. Pour l’arrêter par programmation, utilisez la méthode Terminate dans la classe Win32_Process. Pour plus d’informations, consultez Définition de la sécurité sur un appel asynchrone.

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

Consommateurs d'événements

Vous pouvez effectuer un monitoring des événements ou consommer ces derniers à l’aide des consommateurs suivants pendant l’exécution d’un script ou d’une application :

  • Consommateurs d’événements temporaires

    Un consommateur temporaire est une application cliente WMI qui reçoit un événement WMI. WMI comprend une interface unique qui permet de spécifier les événements que WMI doit envoyer à une application cliente. Un consommateur d’événements est considéré comme étant temporaire dans la mesure où il fonctionne uniquement quand il est chargé spécifiquement par un utilisateur. Pour plus d’informations, consultez Réception d’événements pendant la durée de votre application.

  • Consommateurs d’événements permanents

    Un consommateur permanent est un objet COM qui peut recevoir un événement WMI à tout moment. Un consommateur d’événements permanent utilise un ensemble d’objets et de filtres persistants pour capturer un événement WMI. À l’image d’un consommateur d’événements temporaire, vous configurez une série d’objets et de filtres WMI qui capturent un événement WMI. Quand un événement correspondant à un filtre se produit, WMI charge le consommateur d’événements permanent et lui notifie l’événement. Dans la mesure où un consommateur permanent est implémenté dans le dépôt WMI et qu’il s’agit d’un fichier exécutable inscrit dans WMI, le consommateur d’événements permanent fonctionne et reçoit des événements après sa création, et même après un redémarrage du système d’exploitation tant que WMI est en cours d’exécution. Pour plus d’informations, consultez Réception d’événements à tout moment.

Les scripts ou les applications qui reçoivent des événements ont des considérations de sécurité particulières. Pour plus d’informations, consultez Sécurisation des événements WMI.

Une application ou un script peut utiliser un fournisseur d’événements WMI intégré qui fournit des classes de consommateur standard. Chaque classe de consommateur standard répond à un événement par une action différente en envoyant un e-mail ou en exécutant un script. Vous n’avez pas besoin d’écrire du code fournisseur pour utiliser une classe de consommateur standard afin de créer un consommateur d’événements permanent. Pour plus d’informations, consultez Monitoring des événements et réponse à ces derniers avec des consommateurs standard.

Fourniture d’événements

Un fournisseur d’événements est un composant COM qui envoie un événement à WMI. Vous pouvez créer un fournisseur d’événements pour envoyer un événement dans une application C++ ou C#. La plupart des fournisseurs d’événements gèrent un objet pour WMI, par exemple une application ou un élément matériel. Pour plus d’informations, consultez Écriture d’un fournisseur d’événements.

Un événement planifié ou répétitif est un événement qui se produit à une heure prédéterminée.

WMI fournit les méthodes suivantes pour créer des événements planifiés ou répétitifs pour vos applications :

  • Infrastructure d’événements Microsoft standard.
  • Classe de minuteur spécialisée.

Pour plus d’informations, consultez Réception d’un événement planifié ou répétitif. Quand vous écrivez un fournisseur d’événements, tenez compte des informations de sécurité identifiées dans Fourniture d’événements de manière sécurisée.

Il est recommandé de compiler les abonnements aux événements permanents dans l’espace de noms \root\subscription. Pour plus d’informations, consultez Implémentation d’abonnements permanents à des événements entre espaces de noms.

Quotas d’abonnement

L’interrogation d’événements peut dégrader les performances des fournisseurs qui prennent en charge les requêtes sur des jeux de données volumineux. De plus, tout utilisateur disposant d’un accès en lecture à un espace de noms avec des fournisseurs dynamiques peut effectuer une attaque DoS (déni de service). WMI gère des quotas pour tous les utilisateurs combinés ainsi que pour chaque consommateur d’événements dans l’instance unique de __ArbitratorConfiguration située dans l’espace de noms \root. Ces quotas sont globaux et non spécifiques à chaque espace de noms. Vous ne pouvez pas changer les quotas.

WMI applique des quotas à l’aide des propriétés de __ArbitratorConfiguration. Chaque quota a une version par utilisateur et une version totale qui comprend tous les utilisateurs combinés, et non par espace de noms. Le tableau suivant liste les quotas qui s’appliquent aux propriétés __ArbitratorConfiguration.

Total/PerUser Quota
TemporarySubscriptionsTotal
TemporarySubscriptionsPerUser
10 000
1 000
PermanentSubscriptionsTotal
PermanentSubscriptionsPerUser
10 000
1 000
PollingInstructionsTotal
PollingInstructionsPerUser
10 000
1 000
PollingMemoryTotal
PollingMemoryPerUser
10 000 000 (0x989680) octets
5 000 000 (0x4CB40) octets

Un administrateur ou un utilisateur disposant de l’autorisation FULL_WRITE dans l’espace de noms peut modifier l’instance singleton de __ArbitratorConfiguration. WMI effectue le suivi du quota par utilisateur.

Utilisation de WMI