如何使用UNC路径进行WMI事件监听
How to use UNC path for WMI event monitoring
我正在尝试使用 WMI 通过 vbs 脚本监视文件夹的更改,但它将是一个网络驱动器。有几个用户将执行此脚本,映射的驱动器号可能对某些用户不同。因此,我想使用不会改变的UNC。
我已经尝试将 strDrive 和 strFolder 更改为 UNC 和文件夹的每个组合。脚本执行,但不识别任何事件,除非我使用驱动器号。
' VBScript source code
'WMIFileEvents.vbs
intInterval = "2"
strDrive = "f:" 'or \mypath\
strFolder = "\vbs\"
strComputer = "."
Set objWMIService = GetObject( "winmgmts:" & _
"{impersonationLevel=impersonate}!\" & _
strComputer & "\root\cimv2" )
strQuery = _
"Select * From __InstanceOperationEvent" _
& " Within " & intInterval _
& " Where Targetinstance Isa 'CIM_DataFile'" _
& " And TargetInstance.Drive='" & strDrive & "'" _
& " And TargetInstance.Path='" & strFolder & "'"
Set colEvents = objWMIService. ExecNotificationQuery (strQuery)
WScript.Echo "Monitoring events...[Ctl-C] to end"
Do
Set objEvent = colEvents.NextEvent()
Set objTargetInst = objEvent.TargetInstance
Select Case objEvent.Path_.Class
Case "__InstanceCreationEvent"
WScript.Echo "Created: " & objTargetInst.Name
Case "__InstanceDeletionEvent"
WScript.Echo "Deleted: " & objTargetInst.Name
Case "__InstanceModificationEvent"
WScript.Echo "Modified: " & objTargetInst.Name
End Select
Loop
我很乐意修改此脚本以使用 UNC 或 return 来自 UNC 的驱动器盘符(我也不知道该怎么做)。我愿意离开 VBS 到 VBA 或 shell 如果这样更容易解决。
这是我的解决方案。我发现 Wscript.Network 对象具有 EnumNetworkDrives 属性,它是所有当前使用的驱动器号的列表。然后我只是循环浏览字母表以发现当前未使用的字母并手动将 UNC 映射到它。即使他们已经连接了驱动器,我也只是在最后映射并删除。
这假设用户不是所有可能的驱动器号,这对我来说是安全的。另一种方法是将驱动器号映射回 UNC,以确定当前使用的驱动器是否具有我需要的路径。
我希望有比我笨拙的循环更好的方法来查看一个项目是否在列表中,我愿意接受建议,但它对我有用并且没花很长时间写。
'Establish all letters of the English Alphabet (assuming these can all become drive mappings)
Set driveLetters = CreateObject("System.Collections.ArrayList")
driveletters.add "A:"
driveletters.add "B:"
driveletters.add "C:"
driveletters.add "D:"
driveletters.add "E:"
driveletters.add "F:"
driveletters.add "G:"
driveletters.add "H:"
driveletters.add "I:"
driveletters.add "J:"
driveletters.add "K:"
driveletters.add "L:"
driveletters.add "M:"
driveletters.add "N:"
driveletters.add "O:"
driveletters.add "P:"
driveletters.add "Q:"
driveletters.add "R:"
driveletters.add "S:"
driveletters.add "T:"
driveletters.add "U:"
driveletters.add "V:"
driveletters.add "W:"
driveletters.add "X:"
driveletters.add "Y:"
driveletters.add "Z:"
'Find the first available open drive mapping
Set oWSN = CreateObject("WScript.Network")
Set oDrives = oWSN.EnumNetworkDrives
For i = 0 to driveletters.Count - 1 step 1
in_list = False
For j = 0 to oDrives.Count - 1 Step 2
If oDrives.Item(j) = driveletters.Item(i) Then
in_list = True
End If
Next
If in_list = False Then
strDrive = driveletters.Item(i)
Exit For
End If
Next
oWSN.MapNetworkDrive strDrive, "\unc\path"
'Monitoring code
oWSN.RemoveNetworkDrive strDrive, True
我正在尝试使用 WMI 通过 vbs 脚本监视文件夹的更改,但它将是一个网络驱动器。有几个用户将执行此脚本,映射的驱动器号可能对某些用户不同。因此,我想使用不会改变的UNC。
我已经尝试将 strDrive 和 strFolder 更改为 UNC 和文件夹的每个组合。脚本执行,但不识别任何事件,除非我使用驱动器号。
' VBScript source code
'WMIFileEvents.vbs
intInterval = "2"
strDrive = "f:" 'or \mypath\
strFolder = "\vbs\"
strComputer = "."
Set objWMIService = GetObject( "winmgmts:" & _
"{impersonationLevel=impersonate}!\" & _
strComputer & "\root\cimv2" )
strQuery = _
"Select * From __InstanceOperationEvent" _
& " Within " & intInterval _
& " Where Targetinstance Isa 'CIM_DataFile'" _
& " And TargetInstance.Drive='" & strDrive & "'" _
& " And TargetInstance.Path='" & strFolder & "'"
Set colEvents = objWMIService. ExecNotificationQuery (strQuery)
WScript.Echo "Monitoring events...[Ctl-C] to end"
Do
Set objEvent = colEvents.NextEvent()
Set objTargetInst = objEvent.TargetInstance
Select Case objEvent.Path_.Class
Case "__InstanceCreationEvent"
WScript.Echo "Created: " & objTargetInst.Name
Case "__InstanceDeletionEvent"
WScript.Echo "Deleted: " & objTargetInst.Name
Case "__InstanceModificationEvent"
WScript.Echo "Modified: " & objTargetInst.Name
End Select
Loop
我很乐意修改此脚本以使用 UNC 或 return 来自 UNC 的驱动器盘符(我也不知道该怎么做)。我愿意离开 VBS 到 VBA 或 shell 如果这样更容易解决。
这是我的解决方案。我发现 Wscript.Network 对象具有 EnumNetworkDrives 属性,它是所有当前使用的驱动器号的列表。然后我只是循环浏览字母表以发现当前未使用的字母并手动将 UNC 映射到它。即使他们已经连接了驱动器,我也只是在最后映射并删除。
这假设用户不是所有可能的驱动器号,这对我来说是安全的。另一种方法是将驱动器号映射回 UNC,以确定当前使用的驱动器是否具有我需要的路径。
我希望有比我笨拙的循环更好的方法来查看一个项目是否在列表中,我愿意接受建议,但它对我有用并且没花很长时间写。
'Establish all letters of the English Alphabet (assuming these can all become drive mappings)
Set driveLetters = CreateObject("System.Collections.ArrayList")
driveletters.add "A:"
driveletters.add "B:"
driveletters.add "C:"
driveletters.add "D:"
driveletters.add "E:"
driveletters.add "F:"
driveletters.add "G:"
driveletters.add "H:"
driveletters.add "I:"
driveletters.add "J:"
driveletters.add "K:"
driveletters.add "L:"
driveletters.add "M:"
driveletters.add "N:"
driveletters.add "O:"
driveletters.add "P:"
driveletters.add "Q:"
driveletters.add "R:"
driveletters.add "S:"
driveletters.add "T:"
driveletters.add "U:"
driveletters.add "V:"
driveletters.add "W:"
driveletters.add "X:"
driveletters.add "Y:"
driveletters.add "Z:"
'Find the first available open drive mapping
Set oWSN = CreateObject("WScript.Network")
Set oDrives = oWSN.EnumNetworkDrives
For i = 0 to driveletters.Count - 1 step 1
in_list = False
For j = 0 to oDrives.Count - 1 Step 2
If oDrives.Item(j) = driveletters.Item(i) Then
in_list = True
End If
Next
If in_list = False Then
strDrive = driveletters.Item(i)
Exit For
End If
Next
oWSN.MapNetworkDrive strDrive, "\unc\path"
'Monitoring code
oWSN.RemoveNetworkDrive strDrive, True