WMI for folder add/delete/change in vbscript

S R 1 Reputation point
2020-12-14T12:42:10.107+00:00

I have seen scripts that monitor and report file add/delete/modify in a given folder:

'...  
  
Set colEvents = objWMIService.ExecNotificationQuery _  
        ("SELECT * FROM __InstanceOperationEvent WITHIN 10 WHERE " _  
        & "Targetinstance ISA 'CIM_DirectoryContainsFile' and " _  
        & "TargetInstance.GroupComponent= " _  
        & "'Win32_Directory.Name=""c:\\\\Myfolder\\\\ImportantContent""'")  
  
        Do While True  
            strEmailBody = Now & VbCrLf  
            Set objEvent = colEvents.NextEvent()  
            Select Case objEvent.Path_.Class  
            Case "__InstanceCreationEvent"  
                strEmailBody = strEmailBody & "A new file was just created: " & _  
                objEvent.TargetInstance.PartComponent & VbCrLf  
            Case "__InstanceDeletionEvent"  
                strEmailBody = strEmailBody & "A file was just deleted: " & _  
                objEvent.TargetInstance.PartComponent  
            '' add  "__InstanceModificationEvent"  
            End Select  
            ' do stuff here  
        Loop  
  
'...  
  

Is it possible to detect for a given folder the add/del/change of a sub folder?

For example in C:\data report c:\data\xxx where xxx is a new folder (does not contain files in xxx).

I don't understand these pages enough to construct vbscript for this case I need help with WMI statement and select:

    https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/cim-directorycontainsfile  
    https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/cim-directory  

to replace CIM_DirectoryContainsFile with CIM_Directory - is it possible?

(Am I supposed to post this here because there are no tags for VB scripting)

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,652 questions
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. MotoX80 34,431 Reputation points
    2020-12-15T01:47:54.957+00:00

    VB script isn't being enhanced so I would recommend using Powershell instead.

    Here is a script that appears to do what you need.

    https://gallery.technet.microsoft.com/scriptcenter/Powershell-FileSystemWatche-dfd7084b#content

    Note the comments:

    #This script uses the .NET FileSystemWatcher class to monitor file events in folder(s). 
    #The advantage of this method over using WMI eventing is that this can monitor sub-folders. 
    

    There is no wait loop in that code. So if you test it in Powershell_ise that won't be a problem because that program is still running and can process the fired events. If you get it working and save your code as a .ps1 file, when you execute it with Powershell.exe you will need to use the -NoExit switch. Otherwise the script will register the events and then terminate.

    Depending on how you intend to run the script may require a different solution for keeping Powershell.exe running.

    0 comments No comments

  2. Viorel 118K Reputation points
    2020-12-15T06:45:13.707+00:00

    Try using Win32_SubDirectory instead of CIM_DirectoryContainsFile.

    0 comments No comments

  3. Drake Wu - MSFT 991 Reputation points
    2020-12-15T09:13:58.19+00:00

    Hi, @S R You don't need to use query WMI, you could use this win32 function: ReadDirectoryChangesW. Set the parameter bWatchSubtree as true to monitor the directory tree rooted at the specified directory, and choose the NotifyFilter you are interested in.

    Here is sample code snippet in C++, you could feel free to convert it to VBScript:

        FILE_NOTIFY_INFORMATION* pInfo = NULL;  
        HANDLE hFile = CreateFile(L"folder", GENERIC_READ, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);  
        while (1)  
        {  
            BYTE szBuffer[1024] = { 0 };  
            DWORD dwOffset = 0;  
            DWORD returned = 0;  
            ReadDirectoryChangesW(hFile, szBuffer, sizeof(szBuffer), TRUE, FILE_NOTIFY_CHANGE_FILE_NAME| FILE_NOTIFY_CHANGE_DIR_NAME|FILE_NOTIFY_CHANGE_SIZE, &returned, NULL, NULL);  
            do  
            {  
                pInfo = (FILE_NOTIFY_INFORMATION*)&szBuffer[dwOffset];  
                switch (pInfo->Action)  
                {  
                case FILE_ACTION_ADDED:  
                    std::wcout << L"Added: ";  
                    break;  
                case FILE_ACTION_REMOVED:  
                    std::wcout << L"Removed: ";  
                    break;  
                case FILE_ACTION_MODIFIED:  
                    std::wcout << L"Modified: ";  
                    break;  
                case FILE_ACTION_RENAMED_OLD_NAME:  
                    std::wcout << L"Rename-oldname: ";  
                    break;  
                case FILE_ACTION_RENAMED_NEW_NAME:  
                    std::wcout << L"Rename-newname: ";  
                    break;  
                }  
                std::wcout << L"File Name: " << pInfo->FileName << std::endl;  
                dwOffset += pInfo->NextEntryOffset;  
            } while (pInfo->NextEntryOffset != 0);  
        }  
    

    If the answer is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.