Eventing extensions for PowerShell 2.0 Console Host. This module integrates with PowerShell 2.0 Eventing infrastructure. HotKey events can have a scriptblock action, or can put events in the event queue just like the OOTB eventing cmdlets. This is the recommended
release for PowerShell 2.0 which already has built-in eventing support.
Trap and respond to synchronous & asynchronous .NET, COM and WMI events or Hot Keys within your powershell scripts with this easy to use suite of cmdlets. Compatible with PowerShell 1.0, 2.0 & 3.0
This is intended for PowerShell v1.0 only. PowerShell v2.0 has introduced support for eventing with similarly named cmdlets, but with real-time (interrupt-based) event support.
- Multiple named queue support and default queue with -QueueName parameter
- Better COM support, window message pumping etc.
- NoFlush / Peek parameter support for queue reading
- Get-EventQueue command added for viewing queues and their message counts.
foreground / background swappable downloads in powershell
for an advanced example.
Cmdlet Name Changes
- Get-Event -> Read-Event
- Connect-EventListener -> Connect-Event
- Disconnect-EventListener -> Disconnect-Event
64 bit PowerShell Support
To install for use with the 64bit version of PowerShell, please use the 64bit version of InstallUtil:
& "$env:windir\Microsoft.NET\Framework64\v2.0.50727\InstallUtil.exe" nivot.powershell.eventing.dll
How does it work?
Events in PowerShell - but how? Events in a .NET executable are generally raised and handled in realtime in an asynchronous fashion; at first glance, this doesn't seem possible with our favourite little shell. PowerShell lets us wire up scriptblocks to
.NET events as handlers relatively easily, but unfortunately if the event is raised on a different thread (as is the case with WMI watchers, FileSystemWatchers and other asynchronous objects), there is no runspace available to execute our script. So, how do
we get a runspace to execute a handler? Well, we ensure that we are in a running pipeline before processing events. This is achieved by disconnecting the process: we separate the occurance of events from the act of handling them. How does this work in practice?
Let's play with System.IO.FileSystemWatcher
Example with FileSystemWatcher
This example uses the Cmdlets directly to demonstrate how the Snap-In works; you may find it easier and more familiar to work with the simple wrapper functions supplied on the Releases page. See the bottom of this page to read about these functions, called
1# Add-PSSnapin pseventing
2# $fsw = new-object system.io.filesystemwatcher
3# $fsw.Path = "c:\temp"
4# $fsw.EnableRaisingEvents = $true
This loads our snap-in, creates a FileSystemWatcher
instance assigned to the variable named
and tells it to keep an eye on our temp directory. So, what events can we watch? Well, before you go running to MSDN...
#5 Get-EventBinding fsw -IncludeUnboundEvents | Format-Table -Auto
VariableName EventName TypeName Listening
------------ --------- -------- ---------
fsw Changed FileSystemWatcher False
fsw Created FileSystemWatcher False
fsw Deleted FileSystemWatcher False
fsw Disposed FileSystemWatcher False
fsw Error FileSystemWatcher False
fsw Renamed FileSystemWatcher False
This command lets us examine what events this variable exposes. Note that I say
, and not
object. This is a running theme throughout this library -
all PSEventing Cmdlets only deal with PSVariable objects, or variable names
so do not prefix your variable names with the $ symbol. This will end up passing the instance instead of the variable, which is not what we want. This is to keep the paradigm
similar to other late-bound scripting languages, like vbscript; allowing direct object references would not have been very admin-friendly. Ok, so next, lets watch the
events. Btw, Event names are not case sensitive, unless you provide the
5# Connect-Event fsw changed,deleted
From this moment on, every time something is changed or deleted in c:\temp, a
object is added to our background event queue, even if you're busy running some other script or doing an unrelated task! Lets perform some related activity:
6# "foo" > c:\temp\bar.txt
7# remove-item c:\temp\bar.txt
Now, we've just created and deleted a file. You could have also gone out to explorer and created and deleted the file; all events are captured, not just those triggered from within powershell. How do we find out whap's happened, and act on this info?
with the read-Event
8# $events = Read-Event
9# $events | Format-Table -Auto
Occurred Source Name Args
-------- ------ ---- ----
5/9/2007 3:31:39 PM System.Management.Automation.PSVariable Changed System.IO.FileSystemEventArgs
5/9/2007 3:31:42 PM System.Management.Automation.PSVariable Deleted System.IO.FileSystemEventArgs
Two events occured since we wired up the listener (or since we last called
since each call drains the queue). Lets have a look at the EventArgs for the first one:
10# $events.Args | format-table -Auto
ChangeType FullPath Name
---------- -------- ----
Changed c:\temp\bar.txt bar.txt
And there you have it!
Download the 1.1 release and have a look at the sqlbackup.ps1
example script for more advanced uses.
All cmdlets have -? help support, and you can also get more information via
- Connect-Event : Start tracking one or more event(s) for one or more variable(s)
- Connect-Event [-VariableName] <String> [-EventName] <String> [-CaseSensitive [<SwitchParameter>]] [-QueueName <identifier>] [<CommonParameters>]
- Connect-Event [-Variable] <PSVariable> [-EventName] <String> [-CaseSensitive [<SwitchParameter>]] [-QueueName <identifier>] <CommonParameters>]
- Disconnect-Event : Stop tracking one or more event(s) for one or more variable(s)
- Disconnect-Event [-VariableName] <String> [-EventName] <String> [-CaseSensitive [<SwitchParameter>]] [<CommonParameters>]
- Disconnect-Event [-Variable] <PSVariable> [-EventName] <String> [-CaseSensitive [<SwitchParameter>]] <CommonParameters>]
Hint : bind or unbind all events at once for a variable
- Get-EventBinding : Retrieve event binding information for variables
- Get-EventBinding [[-Variable] [<PSVariable>]] [-IncludeUnboundEvents [<SwitchParameter>]] [<CommonParameters>]
- Get-EventBinding [[-VariableName] [<String>]] [-IncludeUnboundEvents [<SwitchParameter>]] [<CommonParameters>]
1# $fsw = New-Object System.IO.FileSystemWatcher
2# Get-EventBinding fsw -IncludeUnboundEvents | Connect-Event
- New-Event : Create a custom event for insertion into the queue with an optional object payload
- New-Event [-EventName] <String> [[-Data] [<PSObject>]] [-QueueName <identifier>] [<CommonParameters>]
- Read-Event : Retrieve one or more PSEvent objects representing tracked .NET events that have been raised since the last invocation of this command.
- Read-Event [-Wait [<SwitchParameter>]] [-QueueName <identifier>] [-NoFlush <SwitchParameter>] [<CommonParameters>]
- Get-EventQueue : Shows information about the default queue and/or named queues.
- Get-EventQueue [[-QueueName] <String>] [-ShowEmpty] [<CommonParameters>]
- Start-KeyHandler : Start generating PSEvent objects for break (cltr+c) and/or keydown events.
- Start-KeyHandler [-CaptureCtrlC [<SwitchParameter>]] [-CaptureKeys [<SwitchParameter>]] [<CommonParameters>]
- Stop-KeyHandler : Stop generating PSEvent objects for break (ctrl+c) and/or keydown events.
- Stop-KeyHandler [<CommonParameters>]
Read some more
for a quick start.
- Oisin Grehan / x0n