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

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

  • Comments 12
  • Likes
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!

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • <p>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 &gt; if so how can we modify this script</p>

  • <p>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? &nbsp;</p>

  • <p>@Mini you will change the script to monitor for changes to the directory </p>

  • <p>@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: <a rel="nofollow" target="_new" href="http://aka.ms/InsideWMIEvents">http://aka.ms/InsideWMIEvents</a> </p>

  • <p>Hi,</p> <p>I tried the following in Powershell (execute privilege, etc. is OK):</p> <p>get-WmiObject -query &quot;SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE &quot; _</p> <p> &nbsp; &nbsp; &nbsp; &nbsp;&amp; &quot;Targetinstance ISA &#39;CIM_DirectoryContainsFile&#39; and &quot; _</p> <p> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&amp; &quot;TargetInstance.GroupComponent= &quot; _</p> <p> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&amp; &quot;&#39;Win32_Directory.Name=&quot;&quot;c:\\\\temp&quot;&quot;&#39;&quot;</p> <p>The only change I made was to the target directory name. &nbsp;The *&amp;&quot;s did not work. &nbsp;I exchanged the &quot;&amp;&quot;&#39;s for &quot;+&quot;&#39;s and got:</p> <p> &nbsp; &nbsp; Get-WmiObject : A positional parameter cannot be found that accepts argument &#39;+&#39;</p> <p>I removed the &quot;+&quot; and left PS to do its own concatenation and got:</p> <p> &nbsp; &nbsp;Get-WmiObject : A positional parameter cannot be found that accepts argument &#39;Targetinstance ISA &#39;CIM_DirectoryContainsFile&#39; and &#39;.</p> <p>Any suggestions? &nbsp;Am I going down the wrong path? &nbsp;Any help greatly appreciated.</p> <p>DaveAef</p>

  • <p>@DaveAef This article is written using VBScript and not using Windows PowerShell. The &amp; 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.</p>

  • <p>Great script but is it possible to make it monitor the %USERPROFILE% folder? &nbsp;For instance C:\users\username\temp</p>

  • <p>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?</p>

  • <p>@paris</p> <p>Control-C</p>

  • <p>@paris</p> <p>Control-C</p>

  • <p>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?</p>

  • 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?