Welcome PowerShell User! This recipe is just one of the hundreds of useful resources contained in the PowerShell Cookbook.
If you own the book already, login here to get free, online, searchable access to the entire book's content.
If not, the Windows PowerShell Cookbook is available at Amazon, or any of your other favourite book retailers. If you want to see what the PowerShell Cookbook has to offer, enjoy this free 90 page e-book sample: "The Windows PowerShell Interactive Shell".
You want to create new events for other scripts to consume or want to respond automatically when they occur.
Use the New-Event
cmdlet to generate a custom event. Use the -Action
parameter of the Register-EngineEvent
cmdlet to respond to that event automatically.
PS > Register-EngineEvent -SourceIdentifier Custom.Event ` -Action { Write-Host "Received Event" } PS > $null = New-Event Custom.Event Received Event
The New-Event
cmdlet lets you create new custom events for other scripts or event registrations to consume. When you call the New-Event
cmdlet, PowerShell adds a new entry to the sessionwide event repository called the event queue. You can use the Get-Event
cmdlet to see events added to this queue, or you can use the Register-EngineEvent
cmdlet to have PowerShell respond automatically.
One prime use of the New-Event
cmdlet is to adapt complex events surfaced through the generic WMI and .NET event cmdlets. By writing task-focused commands to surface this adapted data, you can offer and work with data that is simpler to consume.
To accomplish this goal, use the Register-ObjectEvent
or Register-CimIndicationEvent
cmdlets to register for one of their events. In the -Action
script block, use the New-Event
cmdlet to generate a new, more specialized event.
In this scenario, the event registrations that interact with .NET or WMI directly are merely “support” events, and users wouldn’t expect to see them when they use the Get-EventSubscriber
cmdlet. To hide these event registrations by default, both the Register-ObjectEvent
and Register-CimIndicationEvent
cmdlets offer a
-SupportEvent
parameter.
Here’s an example of two functions that notify you when a new process starts:
## Enable process creation events
function
Enable-ProcessCreationEvent
{
$identifier
=
"WMI.ProcessCreated"
$query
=
"SELECT * FROM __instancecreationevent "
+
"WITHIN 5 "
+
"WHERE targetinstance isa 'win32_process'"
Register-CimIndicationEvent
-Query
$query
-SourceIdentifier
$identifier
`
-SupportEvent
-Action
{
[void]
(
New-Event
"PowerShell.ProcessCreated"
`
-Sender
$sender
`
-EventArguments
$EventArgs
.
NewEvent
.
TargetInstance
)
}
}
## Disable process creation events
function
Disable-ProcessCreationEvent
{
Unregister-Event
-Force
-SourceIdentifier
"WMI.ProcessCreated"
}
When used in the shell, the experience is much simpler than working with the WMI events directly:
PS > Enable-ProcessCreationEvent PS > calc PS > Get-Event ComputerName : RunspaceId : feeda302-4386-4360-81d9-f5455d74950f EventIdentifier : 2 Sender : System.Management.ManagementEventWatcher SourceEventArgs : SourceArgs : {calc.exe} SourceIdentifier : PowerShell.ProcessCreated TimeGenerated : 2/21/2010 3:15:57 PM MessageData : PS > (Get-Event).SourceArgs (...) Caption : calc.exe CommandLine : "C:\Windows\system32\calc.exe" CreationClassName : Win32_Process CreationDate : 20100221151553.574124-480 CSCreationClassName : Win32_ComputerSystem CSName : LEEHOLMES1C23 Description : calc.exe ExecutablePath : C:\Windows\system32\calc.exe (...) PS > Disable-ProcessCreationEvent PS > notepad PS > Get-Event ComputerName : RunspaceId : feeda302-4386-4360-81d9-f5455d74950f EventIdentifier : 2 Sender : System.Management.ManagementEventWatcher SourceEventArgs : SourceArgs : {calc.exe} SourceIdentifier : PowerShell.ProcessCreated TimeGenerated : 2/21/2010 3:15:57 PM MessageData :
In addition to events that you create, engine events also represent events generated by the engine itself. PowerShell supports three of these: PowerShell.Exiting
to let you do some work when the PowerShell session exits, PowerShell.OnIdle
to let you coordinate activity in a PowerShell session, and PowerShell.OnScriptBlockInvoke
to let you process script blocks before they’re invoked.
For an example of working with the PowerShell.Exiting
event, see Recipe 1.31.
PowerShell treats engine events like any other type of event. You can use the Register-EngineEvent
cmdlet to automatically react to these events, just as you can use the Register-ObjectEvent
and Register-CimIndicationEvent
cmdlets to react to .NET and WMI events, respectively. For information about how to respond to events automatically, see Recipe 31.1.
Recipe 1.31, “Save State Between Sessions”
Recipe 31.1, “Respond to Automatically Generated Events”