Reacting to the Buzz
Last time I began showing you how to take advantage of event subscriptions in PowerShell. Specifically, we looked at how to watch for changes to things that are captured in WMI, such as a service stopping or a process starting. I showed you how to register an event subscriber:
$query ="Select * from __InstanceModificationEvent WITHIN 5 Where TargetInstance ISA 'win32_service' AND TargetInstance.Name='Spooler' AND TargetInstance.State='Stopped'"
Register-CimIndicationEvent -query $query -SourceIdentifier "SpoolerStop"
This simple subscription, waits for the event, and when it happens, captures it.
PS C:\> Stop-Service Spooler
PS C:\> Get-Event
ComputerName :
RunspaceId : 53e685ce-e222-414e-819e-1bad0ae188f0
EventIdentifier : 1
Sender : Microsoft.Management.Infrastructure.CimCmdlets.CimIndicationWatcher
SourceEventArgs : Microsoft.Management.Infrastructure.CimCmdlets.CimIndicationEventInstanceEventArgs
SourceArgs : {Microsoft.Management.Infrastructure.CimCmdlets.CimIndicationWatcher, }
SourceIdentifier : SpoolerStop
TimeGenerated : 9/8/2025 8:53:31 AM
MessageData :
I showed you how to drill down into the event to see what was captured. However, there is another option you might find useful. You can add a custom message to the event subscription.
$query = "Select * from __InstanceCreationEvent within 10 Where TargetInstance ISA 'Win32_UserAccount'"
Register-CimIndicationEvent -query $query -SourceIdentifier NewAccount -ComputerName Cadenza -MessageData "A new user account has been created on CADENZA"
> Do not run this command to monitor a domain controller.
This is event subscriber is watching for new user accounts to be created on a remote computer named CADENZA. When a new account is created, the event is captured, and the message "A new user account has been created on CADENZA" is added to the event.
PS C:\> Get-Event -SourceIdentifier NewAccount
ComputerName :
RunspaceId : 53e685ce-e222-414e-819e-1bad0ae188f0
EventIdentifier : 2
Sender : Microsoft.Management.Infrastructure.CimCmdlets.CimIndicationWatcher
SourceEventArgs : Microsoft.Management.Infrastructure.CimCmdlets.CimIndicationEventInstanceEventArgs
SourceArgs : {Microsoft.Management.Infrastructure.CimCmdlets.CimIndicationWatcher, }
SourceIdentifier : NewAccount
TimeGenerated : 9/8/2025 9:21:56 AM
MessageData : A new user account has been created on CADENZA
Yes, I can still drill down into the event to see what was captured.
PS C:\> (Get-Event -SourceIdentifier NewAccount).SourceEventArgs.NewEvent.TargetInstance
Name Caption AccountType SID Domain
---- ------- ----------- --- ------
alfresco Cadenza\alfresco 512 S-1-5-21-3998709781-1337716678-2240924477-1004 Cadenza
However the message might be all I need to know.
But what if I want to do something when the event happens? What if I want to be notified by email or log the event to a file? You can do that too. You can use the -Action
parameter of the Register-CimIndicationEvent
cmdlet to specify a script block that will run when the event is captured.
$query = "Select * from __InstanceCreationEvent within 10 Where TargetInstance ISA 'Win32_UserAccount'"
Register-CimIndicationEvent -query $query -SourceIdentifier NewAccount -ComputerName Cadenza -Action {
param($event)
# Do something with the event
#$event.SourceEventArgs.NewEvent
}
When you use an action script block, PowerShell creates a background job to run the script block. The fired event is passed to the script block It is not passed to the event queue, so you'll never see it when you run Get-Event
.
You technically don't need to declare the $event
parameter in the script block. By default the event object is passed to the script block, in much the way same way that a Catch
block catches the exception object. The event object is the same thing we worked with earlier when calling Get-Event
.
I'm going to remove the event subscription and re-create it with an action script block that does something useful. In this case, I'll create a file in C:\temp
that contains the details of the new account, and I'll also display a pop-up message to alert me that a new account has been created.
PS C:\> $query = "Select * from __InstanceCreationEvent within 10 Where TargetInstance ISA 'Win32_UserAccount'"
PS C:\> Register-CimIndicationEvent -query $query -SourceIdentifier NewAccount -ComputerName Cadenza -Action {
#formatting pattern is case-sensitive
#export the new account info
$fileName = "{0:yyyyMMddhhmmss}-NewAccount.xml" -f (Get-Date)
$filePath = Join-Path -path C:\temp -Childpath $fileName
[PSCustomObject]@{
Date = $event.TimeGenerated
Data = $event.SourceEventArgs.NewEvent.TargetInstance
} | Export-Clixml -path $filePath
#show a pop up alert
$alert = "A new user account {0} has been created on Cadenza" -f $event.SourceEventArgs.NewEvent.TargetInstance.Caption
#msg is a built-in command line tool to show a pop up message
msg * $alert
}
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
11 NewAccount NotStarted False …