Monitoring file creation using WMI and PowerEvents module

There are several ways we can create a file monitoring script using PowerShell. There is also a cmdlet in PowerShellPack called Start-FileSystemWatcher to monitor file /folder changes. However, none of these methods survive a exit at the console or wherever the script is running. This is because all these methods create a temporary event consumer. As I’d mentioned in an earlier post, Trevor’s PowerEvents module makes it very easy to create permanent event consumers in PowerShell. In today’s post, we shall look at how we can do that.

Before we dig into that, let us first see how we can create a file monitoring script using PowerShell. Many people use CIM_DirectoryContainsFile class and create an event listener. This is how we use do that class in PowerShell.

$query = "Select * from __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA 'CIM_DirectoryContainsFile' AND TargetInstance.GroupComponent='Win32_Directory.Name=""C:\\\\Scripts""'"
Register-WmiEvent -Query $query -Action {
        Write-Host "A new file $($event.SourceEventArgs.NewEvent.TargetInstance.PartComponent) got created"
    }
CIM_DirectoryContainsFile

CIM_DirectoryContainsFile

As you see in the above output, what we get as a part of event data is just that string contained in $Event.SourceEventArgs.NewEvent.TargetInstance.PartComponent. Of course, if you are RegEx lover, you’d just parse that and find the name (extension, etc) of the new file that just got created. However, there is an efficient and easy way to do that. And, that is: monitoring the CIM_DataFile class itself. This is how we do it:

$query = "Select * from __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA 'CIM_DataFile' AND TargetInstance.Drive='C:' AND TargetInstance.Path='\\Scripts\\'"
Register-WmiEvent -Query $query -Action {
        $event.SourceEventArgs.NewEvent.TargetInstance | Select -Expand FileName, Extension, Name | Out-Host
    }

And, this is what we see in the output.

Using CIM_DataFile

Using CIM_DataFile

We selected only a few properties from the available list of properties. But, this should give you an idea why I prefer using CIM_DataFile as compared to CIM_DirectoryContainsFile when monitoring for file creation. Similarly, we can monitor file deletions and modifications by subscribing to __InstanceDeletionEvent and __InstanceModificationEvent. The usage of these two classes is more or less similar. So, I will skip those aspects in this post.

However, as I mentioned earlier, we are only creating temporary event consumers by using Register-WMIEvent cmdlet. This is not really helpful since we have to keep the console window where we registered the event always open. We can solve this problem by using a permanent WMI event consumer. This is what PowerEvents module does. It helps us create any of the five permanent WMI consumers.

So, for todays post, we shall look at creating a log file consumer using PowerEvents module.

First, we need download and import the module using Import-Module cmdlet. Once this is done, we need to create an event filter for the event we want to subscribe. This is done using New-WMIEventFilter cmdlet.

$query = "Select * from __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA 'CIM_DataFile' AND TargetInstance.Drive='C:' AND TargetInstance.Path='\\Scripts\\'"
$eventFilter = New-WmiEventFilter -Name "FileMonitor" -Query $query

Now, we need to create a event consumer. In this case, a log file consumer.

$eventConsumer = New-WmiEventConsumer -ConsumerType LogFile -Name NewFileCreated -FileName C:\Logs\FileMonitor.log `
 -Text "New File has been created: %TargetInstance.Name%"

Once we have both filter and consumer, we can bind them together to create the permanent event consumer.

#This is how we create a binding
New-WmiFilterToConsumerBinding -Filter $eventFilter -Consumer $eventConsumer

This is it. Now, whenever a file gets created in the C:\Scripts folder, we’ll see a entry in the log file at C:\Logs\FileMonitor.log. It’d look like:

Permanent Consumer

Permanent Consumer

These log entries will appear even after a system reboot. This is the benefit of WMI permanent consumers. If you want to learn more about WMI query language syntax used in this post, refer to my WQL series.

  • Pingback: Tweets that mention Monitoring file creation using WMI and PowerEvents module -- Topsy.com

  • http://www.ravichaganti.com/blog Ravikanth

    Testing comments using DISQUS. The WP commenting system was screwed up for some reason.

  • Pingback: Episode 135 – Adam Driscoll and the New vWorkspace PowerShell Module « PowerScripting Podcast

  • Job Vermeulen

    The link to the installation of PowerEvents is empty..

  • Job Vermeulen

    How can i unsubscribe to the events?

  • http://www.ravichaganti.com/blog Ravikanth
  • http://www.ravichaganti.com/blog Ravikanth

    http://powerevents.codeplex.com/ has a GUI app to delete the consumer / filter bindings.

  • Dev

    Hi Ravikanth, thanks for the post. This is what i have below. It compiles, but does not sense the file. Your input would be appreciated.

    EXECmsdb.dbo.sp_add_alert @name=N’Watcher’, @message_id=0, @severity=0, @enabled=1, @delay_between_responses=0, @include_event_description_in=0, @category_name=N’[Uncategorized]‘,msdb.dbo.sp_add_alert @name=N’Watcher’, @message_id=0, @severity=0, @enabled=1, @delay_between_responses=0, @include_event_description_in=0, @category_name=N’[Uncategorized]‘,=0, @severity=0, @enabled=1, @delay_between_responses=0, @include_event_description_in=0, @category_name=N’[Uncategorized]‘,=0, @enabled=1, @delay_between_responses=0, @include_event_description_in=0, @category_name=N’[Uncategorized]‘,=1, @delay_between_responses=0, @include_event_description_in=0, @category_name=N’[Uncategorized]‘,=0, @include_event_description_in=0, @category_name=N’[Uncategorized]‘,=0, @category_name=N’[Uncategorized]‘,=N’[Uncategorized]‘,@wmi_namespace=N’\.rootcimv2′, @wmi_query=N’ SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE TargetInstance ISA ”CIM_DirectoryContainsFile” and TargetInstance.GroupComponent= ”Win32_Directory.Name=”\\\\machine\\folder1\\folder2””’,=N’\.rootcimv2′, @wmi_query=N’ SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE TargetInstance ISA ”CIM_DirectoryContainsFile” and TargetInstance.GroupComponent= ”Win32_Directory.Name=”\\\\machine\\folder1\\folder2””’,=N’ SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE TargetInstance ISA ”CIM_DirectoryContainsFile” and TargetInstance.GroupComponent= ”Win32_Directory.Name=”\\\\machine\\folder1\\folder2””’,,@job_id=N’fb4ffed2-7456-480b-99f5-94524d2dff00’=N’fb4ffed2-7456-480b-99f5-94524d2dff00’GO

  • Sap_dreams12

    Hi Ravikanth,

    I want the list of fielnames and type from the query below in the SMTPConsumer Message but when iam using Group within it is not triggerign email when i remove group it is shootign email can you pls advice

    instance of __EventFilter as $EventFilter{    Name  = “File Copy Filter”;    EventNamespace = “Root\Cimv2″;    Query =”SELECT * From __InstanceCreationEvent WITHIN 10 Where TargetInstance ISA ‘CIM_DATAFile’AND TargetInstance.Drive=’D:’GROUP WITHIN 10″;    QueryLanguage = “WQL”;};
    // 3. Create an instance of __EventConsumer//    derived class. (ActiveScriptEventConsumer//    SMTPEventConsumer etc…)
    instance of SMTPEventConsumer as $SMTPConsumer{    Name = “File Copy SMTP Consumer”;    Message = “A File Named %TargetInstance”;    SMTPServer = “xyz”;    Subject = “File Copy to USB on Computer %TargetInstance.CSName%”;    ToLine = “xyz”;    FromLine = “%TargetInstance.CSName%@xyz.com”;};