How Can I Automatically Run a Script Any Time a File is Added to a Folder?


Hey, Scripting Guy! Question

Hey, Scripting Guy! Is it possible to have a script automatically run any time a file is added to a specific folder?

— MB

SpacerHey, Scripting Guy! AnswerScript Center

Hey, WM. Yes, this is possible, thanks to the magic of WMI events, which allow you to write a script to monitor for something of interest (like a file being added to a folder) and then take some action any time an event like that occurs. We don’t have time to discuss WMI events in any detail in this column, but they can be incredibly useful to script writers. Consequently, it might be worth your while to check out this Tales from the Script column.


In the meantime, here’s a script that monitors the C:\Scripts folder. Any time a file is added to this folder, the script responds by echoing the name of that new file:

strComputer = “.”
Set objWMIService = GetObject(“winmgmts:” _
& “{impersonationLevel=impersonate}!\\” & _
strComputer & “\root\cimv2”)
Set colMonitoredEvents = objWMIService.ExecNotificationQuery _
(“SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE ” _
& “Targetinstance ISA ‘CIM_DirectoryContainsFile’ and ” _
& “TargetInstance.GroupComponent= ” _
& “‘Win32_Directory.Name=””c:\\\\scripts””‘”)
Do
Set objLatestEvent = colMonitoredEvents.NextEvent
Wscript.Echo objLatestEvent.TargetInstance.PartComponent
Loop

Again, there’s too much going on here to go through the script step-by-step, but what we are looking for are instances of the __InstanceCreationEvent class; instances of this class are automatically created any time a new managed object (that is, something WMI knows about) is created on a computer. Although the query is a little complicated, it boils down to this: we want to be alerted to any new items that show up in C:\Scripts. (Note that C:\\\\Scripts is not a misprint; you really need all four slashes here.)


We also need to mention that a WMI script like this works by “polling;” it periodically goes out and checks to see if any new files have been added to the folder. For this sample, we’re checking every 10 seconds (that’s what the WITHIN 10 represents) to see if there are any new files in the folder. If that’s too fast or too slow, you can change that value to anything you want. Keep in mind two things, however. For one, if you poll too often (say, every second), you’ll have a script that is constantly running, and could theoretically put a drain on your system resources.


Conversely, if you make the value too long, you might miss new files, assuming they get added and then deleted before the polling time expires. For example, say your script checks every 5 minutes for new files. If you add 100 new files and then delete all those files 3 minutes later, the script will never know that those files were added to the folder. That’s because scripts like this work by comparing the files that currently in the folder with the files that were in the folder the last time the script checked. Play around with the polling interval and see what works best for you.


As we noted, this script simply echoes the name of any new file added to C:\Scripts. What if you wanted to do something a little fancier any time a file is added to the folder? No problem; just replace this line of code with the code you want executed any time a new file is detected:

Wscript.Echo objLatestEvent.TargetInstance.PartComponent

By the way, would you prefer to be notified any time a file is deleted from C:\Scripts? That’s easy enough; just monitor C:\Scripts for new instances of the __InstanceDeletionEvent class:

strComputer = “.”
Set objWMIService = GetObject(“winmgmts:” _
& “{impersonationLevel=impersonate}!\\” & _
strComputer & “\root\cimv2”)
Set colMonitoredEvents = objWMIService.ExecNotificationQuery _
(“SELECT * FROM __InstanceDeletionEvent WITHIN 10 WHERE ” _
& “Targetinstance ISA ‘CIM_DirectoryContainsFile’ and ” _
& “TargetInstance.GroupComponent= ” _
& “‘Win32_Directory.Name=””c:\\\\scripts””‘”)
Do
Set objLatestEvent = colMonitoredEvents.NextEvent
Wscript.Echo objLatestEvent.TargetInstance.PartComponent
Loop

Hey, we told you WMI events were worth knowing about!

Comments (24)

  1. jrv says:

    @paris

    Control-C

  2. Anonymous says:

    Is it possible to monitor a folder on a remote machine (in a workgroup so I have to pass the login info) with this script and move the file to the local machine when a file gets created?  

  3. Anonymous says:

    Hi,

    I tried the following in Powershell (execute privilege, etc. is OK):

    get-WmiObject -query "SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE " _

           & "Targetinstance ISA 'CIM_DirectoryContainsFile' and " _

               & "TargetInstance.GroupComponent= " _

                   & "'Win32_Directory.Name=""c:\\temp""'"

    The only change I made was to the target directory name.  The *&"s did not work.  I exchanged the "&"'s for "+"'s and got:

        Get-WmiObject : A positional parameter cannot be found that accepts argument '+'

    I removed the "+" and left PS to do its own concatenation and got:

       Get-WmiObject : A positional parameter cannot be found that accepts argument 'Targetinstance ISA 'CIM_DirectoryContainsFile' and '.

    Any suggestions?  Am I going down the wrong path?  Any help greatly appreciated.

    DaveAef

  4. mini says:

    how can i use this sript to find file in a folder eg i have script folder inside script i have 10 different subfolders.I have to know when a new file is added to scrip[t folder can we do that > if so how can we modify this script

  5. Ed Wilson says:

    @Mini you will change the script to monitor for changes to the directory

  6. ed wilson says:

    @Ittechstop you do not want to use this on a permanent basis … this is a temporary event. You can change it to be a permanent event and then it would do exactly what you want. Look at this collection of articles that will explain the differences between temporary and permanent WMI events: http://aka.ms/InsideWMIEvents

  7. Ed Wilson says:

    @DaveAef This article is written using VBScript and not using Windows PowerShell. The & character, which is concatenation in VBScript is the invocation operator in PowerShell. The space underscore is line continuation in VBScript. As it turns out, this week, I wrote about this topic. Go to the archives, and look at the Hey Scripting Guy articles for the week of July 16, 2012. You will see where I modify this query and use it in Windows PowerShell.

  8. Chris says:

    Great script but is it possible to make it monitor the %USERPROFILE% folder?  For instance C:usersusernametemp

  9. paris says:

    We can stop the script using Windows Task Manager and looking for wscript.exe in the Processes, but how would we do that using WMI and scripting?

  10. JV says:

    @paris

    Control-C

  11. Ozi says:

    Hey is it possible to check the file being added to a drive as a whole, Rather then giving c:////Scripts can we give C:/ just?

  12. MicroSeismic Tech says:

    Is it possible to get an email notification if it detects files not being written to the folder or subfolder within the last 5 minutes?

  13. Chad Wingo says:

    I have the exact same question as MicroSeismic Tech. We have a server that has quality control data written to folders once a minute. If services stops for whatever reason, currently we have no way of knowing until it’s too late and our Quality department
    goes back to look at data from a few months back and there is no data because the service had stopped. I would love to receive an email notification if the folder has not been written to in ‘x’ amount of minutes.

  14. thierry says:

    Hello, the code doesn’t work on my computer. I just change the directory name,

    strComputer = "."
    Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\" & _
    strComputer & "rootcimv2")
    Set colMonitoredEvents = objWMIService.ExecNotificationQuery _
    ("SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE " _
    & "Targetinstance ISA ‘CIM_DirectoryContainsFile’ and " _
    & "TargetInstance.GroupComponent= " _
    & "’Win32_Directory.Name=""C:Local""’")
    Do
    Set objLatestEvent = colMonitoredEvents.NextEvent
    Wscript.Echo objLatestEvent.TargetInstance.PartComponent
    Loop

    The error i get is SWbemServicesEx: Demande non analysable.

    Is there something wrong with CurrentCulture, i’m at paris.
    Thanks in advance for help.

    Ps: Sorry for my english, it is under construction. 🙂

  15. Dan_IT says:

    Hi,

    im trying to create a script to recognise when a new folder has been created in a parent folder i.e. 2014 -> january ->01 . the 01 is the folder i need to be notified of the creation. is this possible? it only happens once a day but needs notify me if it does
    happen.

    thank you so much in advance.

    Dan AMBCS

  16. Ally says:

    hi!
    I am new in using scripts, is that VB? or some other scripting langauges

  17. sam says:

    Very informative! I was wondering how we could copy the new file that was just added to C:Scripts to another location on the network.

  18. Keith says:

    Could we use this script to print a pdf file when it arrives in the folder?

  19. J Ford says:

    I’m not a programmer but can someone direct me to a place that will tell me how to write a script that will activate when I put a file in a folder that will automatically change the file extension to something different?
    jarwayfor@gmail.com

  20. Scoobs says:

    Hello, Thanks for your script 🙂

    I need to detect the creation of new files for c:users%username%appdatalocalmicrosoftoutlook folder.

    How can I change your script to do this? I cant a working script with %username% variable

    Thanks

  21. Hari says:

    Hi.. Is it possible to attach the newly created file and send it across in an email ?

  22. Artur Rutkowski says:

    Hi, when I run the code I get the following error: Quota violation; code: 8004106C; Source: SWbemServicesEx. I found that solution to the problem is to Raise the memory quota of the WMI Provider. But I cannot do it. I am at the limit at the moment. The
    folder that I am interested in monitoring has over 12 000 items, so I assume that not enough quota memory if the problem in this case.
    Is there any workaround for this problem?

  23. rkm says:

    I tried running the following script under vbscript. The result was the following code
    which had a reported error:
    Unparsable query. Code: 80041058 Source: SWbemServicesEx
    can anyone see what the problem is?

    ‘fi_mon1.vbs
    ‘ copied from https://blogs.technet.microsoft.com/heyscriptingguy/2004/10/11/
    ‘ How Can I Automatically Run a Script Any Time a File is Added to a Folder?
    ‘ replaced “smart” quotes by “dumb” quotes and ‘?’ following cimv2 with (“)

    strComputer = “.”

    Set objWMIService = GetObject(“winmgmts:” _
    & “{impersonationLevel=impersonate}!\\” & _
    strComputer & “\root\cimv2”)

    ‘ Reports Error: Unparsable query. Code: 80041058 Source: SWbemServicesEx in following line
    Set colMonitoredEvents = objWMIService.ExecNotificationQuery _
    (“SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE ” _
    & “Targetinstance ISA ‘CIM_DirectoryContainsFile’ and ” _
    & “TargetInstance.GroupComponent= ” _
    & “‘Win32_Directory.Name=””c:\\\\scripts””‘”)
    Do
    Set objLatestEvent = colMonitoredEvents.NextEvent
    Wscript.Echo objLatestEvent.TargetInstance.PartComponent
    Loop

Skip to main content