PowerShell Eventing
This isn’t the latest sport added for the 2012 Olympics but a way to dig deeper into what is happening on your machine. There is a continuous stream of events occurring on a computer – programs stop or start, files open or close etc etc. Some, but all, of these events are recorded in the event logs. If we want to understand what is happening we can track this using the PowerShell Event engine that is introduced in PowerShell v2.
Three types of events can be registered – PowerShell engine, .NET and WMI using the following cmdlets respectively
Register-EngineEvent
Register-ObjectEvent
Register-WmiEvent
We can use the following cmdlets to discover the events that actually happen.
Get-Event
Get-EventSubscriber
New-Event
Remove-Event
Unregister-Event
Wait-Event
We’ll start by looking at WMI events. We can use Register-WmiEvent to register the event we want to track. In this case we want to know when new processes are started. We can create an event registration using
Register-WmiEvent -Query "Select * from __instancecreationevent within 5 where targetinstance isa 'Win32_Process'" -MessageData "Process Started" -SourceIdentifier "New Process"
__instancecreationevent is a WMI System Class. 5 refewrs to the system being scanned every 5 seconds
WMI System classes are created on a per WMI namespace basis i.e. a new set of system classes is created for each WMI namespace. The full list of WMI system classes can be seen at http://msdn.microsoft.com/en-us/library/aa394583(VS.85).aspx or can be browsed using PowerGUI's WMI browser.
We can view the system classes relating to WMI events.
Get-WmiObject -Namespace 'root\cimv2' -List "__*Event"
and we will see that there is a __InstanceDeletionEvent class as well. if we want to track process creation and deletion (program open and close) we will need to register this as well.
Register-WmiEvent -Query "Select * from __instancedeletionevent within 5 where targetinstance isa 'Win32_Process'" -MessageData "Process Stopped" -SourceIdentifier "End Process"
When we run these commands nothing seems to happen. We can see the event registrations (or subscriptions)
PS> Get-EventSubscriber
SubscriptionId : 1
SourceObject : System.Management.ManagementEventWatcher
EventName : EventArrived
SourceIdentifier : New Process
Action :
HandlerDelegate :
SupportEvent : False
ForwardEvent : False
SubscriptionId : 2
SourceObject : System.Management.ManagementEventWatcher
EventName : EventArrived
SourceIdentifier : End Process
Action :
HandlerDelegate :
SupportEvent : False
ForwardEvent : False
If we start notepad and and then check the process
PS> Get-Process notepad | select name, starttime
Name StartTime
---- ---------
notepad 07/11/2009 14:20:19
we can compare this to the event information
PS> Get-Event -SourceIdentifier "New Process"
ComputerName :
RunspaceId : 2a581963-55cd-4e46-82ab-ddb6a38fa9a2
EventIdentifier : 27
Sender : System.Management.ManagementEventWatcher
SourceEventArgs : System.Management.EventArrivedEventArgs
SourceArgs : {System.Management.ManagementEventWatcher, System.Management.EventArrivedEventArgs}
SourceIdentifier : New Process
TimeGenerated : 07/11/2009 14:20:23
MessageData : Process Started
Which doesn’t seem to tell is much beyond the fact that a process has started – it specifically doesn’t tell us which process has started.
Similarly when we stop a process
PS> Stop-Process -Name notepad
PS> Get-Event -SourceIdentifier "End Process"
ComputerName :
RunspaceId : 2a581963-55cd-4e46-82ab-ddb6a38fa9a2
EventIdentifier : 29
Sender : System.Management.ManagementEventWatcher
SourceEventArgs : System.Management.EventArrivedEventArgs
SourceArgs : {System.Management.ManagementEventWatcher, System.Management.EventArrivedEventArgs}
SourceIdentifier : End Process
TimeGenerated : 07/11/2009 14:27:47
MessageData : Process Stopped
We get a message that the process has stopped but no identification as to which process.
Events only exist in the current session and the subscriptions are lost if the PowerShell session is closed.
Couple of quick points
The event queue can be quickly cleaned using
Get-Event | Remove-Event.
We can remove event subscriptions using
Unregister-Event -SourceIdentifier "New Process"
Unregister-Event -SourceIdentifier "End Process"
We will dig further into the eventing capabilities in future posts