SoFunction
Updated on 2025-03-10

Use vbs to determine the connection time of the removable drive

ask:
Hello, script expert! How to determine the connection time of USB flash drive?
-- PS
answer:
Hello, PS. Yes, we admit: script experts are really lazy. (Especially on Friday, this day we have to write a Monday column.) There may be a way to specifically monitor when a USB flash drive is plugged in. However, we can't find this method, at least we can't find it right away. Admittedly, maybe we may feel a little difficult. However, we decided to write a script that tells you how long any removable drive is connected (or disconnected) to your computer. We hope this will provide you with some added value and flexibility.
Hi, we didn't say we did provide you with added value and flexibility. We just hope we can do it.
Actually, this is a small script that is easy to write. In addition, it has another advantage, which is that it can run on any version of Windows. (Initially, we wanted to use the Win32_VolumeChangeEvent class to complete this task without thinking, but this specific WMI class can only be found on Windows Server 2003.)
The code is as follows:
Copy the codeThe code is as follows:

strComputer = "." 
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") 
Set colEvents =  _ 
    ("Select * From __InstanceOperationEvent Within 10 Where " _ 
        & "TargetInstance isa 'Win32_LogicalDisk'") 
Do While True 
    Set objEvent =  
    If  = 2 Then  
        Select Case objEvent.Path_.Class 
            Case "__InstanceCreationEvent" 
                 "Drive " &  & _ 
                    " has been added." 
            Case "__InstanceDeletionEvent" 
                 "Drive " &  & _ 
                    " has been removed." 
        End Select 
    End If 
Loop 

Yes, it does look like the screensaver monitoring script we showed you a few days ago. We want to reuse the same script to provide you with added value and flexibility. (Although this is mainly to ensure we can save energy.)
This script first connects to the WMI service on the local computer. Then, we issue the following query:
Set colEvents =  _
    ("Select * From __InstanceOperationEvent Within 10 Where " _
        & "TargetInstance ISA 'Win32_LogicalDisk'")
What is the function of this query? Well, here we are going to use the ExecNotificationQuery method to subscribe to a specific set of WMI events. What WMI event? (Man, you have too many questions, aren't you?) In this case, we expect we'll be notified every time we change the instance of the Win32_LogicalDisk class. As you can see right away, these changes will include: creating a new instance of the class (i.e. adding a removable drive) and deleting an existing instance of the class (i.e. taking a removable drive). Within 10  just means that every 10 seconds we will check to see if any Win32_LogicalDisk instances have changed.
Yes, that also means that if you plug in a removable drive and then remove it after 6 seconds, then we probably would never know about it. If this is a problem, change 10 to a smaller value. You can also change 10 to a larger value. For example, changing 10 to 60 will take a check every 60 seconds, rather than every 10 seconds.
Do you understand? We even added value and flexibility to the code itself!
Then, we set up a running Do loop::
Do While True
Next we encountered the following line of code:
Set objEvent = 
As we said in the previous column, this line of code will cause the script to "break", which means that the script will pause this line until the Win32_LogicalDisk class changes. This change (can be created a new instance or delete/modify an existing instance) will cause the script to execute the rest of the code lines in the Do loop.
Good question: What exactly do the remaining lines of code do? Well, first look at whether the drive that generated the event happens to be a removable drive (at least for WMI, DriveType is 2):
If  = 2 Then
If DriveType is not 2, then we can only loop and wait for the next event to occur. If DriveType is equal to 2, then we use the Select Case block to determine which type of event is happening. We can do this by determining the Class of the event:
Select Case objEvent.Path_.Class
Why do this? There are two reasons: First, we don't care about any changes that occur in existing instances. For example, we do not care whether the available drive space on drive C has changed. If you look at the Select Case code, you will notice that we don't bother to check the __InstanceModificationEvent. why not? Because we don't care about __InstanceModificationEvent (the type of event generated when modifying an existing instance in some way).
Second, we want to distinguish between __InstanceCreationEvent (which tells us that a new drive has been created) and __InstanceDeletionEvent (which tells us that an existing drive has been deleted). By determining the event type, we can echo different (and corresponding) messages. For example, here is the code to determine whether a new drive was created, and if so, echo a message indicating the result:
Case "__InstanceCreationEvent"
     "Drive " &  & _
        " has been added."
Here is the code to notify us whether we have deleted an existing drive:
Case "__InstanceDeletionEvent"
     "Drive " &  & _
        " has been removed."
After echoing the corresponding message, we recirculate and wait for the next event to occur. By default, the script will run forever, or at least it will be until you terminate the script process. Execute the code first whenever the situation occurs.
As we said, this is not what you really want, but it does do that. Oh, don't forget the added value and flexibility. This should be enough to make up for the fact that we are not really answering your question. (We hope we've answered one aspect of the question. This is not your question, though.)