Can anyone help me where i do mistake ?
this script is for monitoring folder for create, delete or modified text files
sPath = "C:\scripts\test"
sComputer = "."
sDrive = split(sPath,":")(0)
sFolders1 = split(sPath,":")(1)
sFolders = REPLACE(sFolders1, "\", "\\") & "\\"
Set objWMIService = GetObject("winmgmts:\\" & sComputer & "\root\cimv2")
Set colMonitoredEvents = objWMIService.ExecNotificationQuery _
("SELECT * FROM __InstanceOperationEvent WITHIN 1 WHERE " _
& "TargetInstance ISA 'CIM_DataFile' AND " _
& "TargetInstance.Drive='" & sDrive & "' AND " _
& "TargetInstance.Path='" & sFolders & "' AND " _
& "TargetInstance.Extension = 'txt' ")
Wscript.Echo vbCrlf & Now & vbTab & _
"Begin Monitoring for a Folder " & sDrive & ":" & sFolders1 & " Change Event..." & vbCrlf
Do
Set objLatestEvent = colMonitoredEvents.NextEvent
Select Case objLatestEvent.Path_.Class
Case "__InstanceCreationEvent"
WScript.Echo Now & vbTab & objLatestEvent.TargetInstance.FileName & "." & objLatestEvent.TargetInstance.Extension _
& " was created" & vbCrlf
Case "__InstanceDeletionEvent"
WScript.Echo Now & vbTab & objLatestEvent.TargetInstance.FileName & "." & objLatestEvent.TargetInstance.Extension _
& " was deleted" & vbCrlf
Case "__InstanceModificationEvent"
If objLatestEvent.TargetInstance.LastModified <> _
objLatestEvent.PreviousInstance.LastModified then
WScript.Echo Now & vbTab & objLatestEvent.TargetInstance.FileName & "." & objLatestEvent.TargetInstance.Extension _
& " was modified" & vbCrlf
End If
End Select
Loop
Set objWMIService = nothing
Set colMonitoredEvents = nothing
Set objLatestEvent = nothing
This script is run perfect when i write
sPath = "\\ComputerName\C$\scripts\test"
insted of
sPath = "C:\scripts\test"
Thank you....
If you google for "WMI TargetInstance.Drive", you'll see that the drive letter needs a colon. A query like
SELECT * FROM __InstanceOperationEvent WITHIN 1 WHERE TargetInstance ISA 'CIM_DataFile' AND TargetInstance.Drive='E:' AND TargetInstance.Path='\\trials\\SoTrials\\answers\\10041057\\data\\' AND TargetInstance.Extension = 'txt'
works as expected.
Related
I would like to be able run some custom vb script code upon filename change (for instance to keep a list of newly created files or the ones which changed their name).
The vbs should be called on every filename change happening within a specified folder.
I know how to do that with a full directory scan but I would like to find a more efficient method, for instance by the mean of a sort of OS hook calling my code.
Any way to do that ?
Thank you,
A.
There are two simple WMI examples, tracing changes for *.txt files in C:\Test\ folder.
First one is for synchronous event processing:
Option Explicit
Dim oWMIService, oEvents, s
Set oWMIService = GetObject("WinMgmts:\\.\root\CIMv2")
Set oEvents = oWMIService.ExecNotificationQuery( _
"SELECT * FROM __InstanceOperationEvent " & _
"WITHIN 1 WHERE " & _
"TargetInstance ISA 'CIM_DataFile' AND " & _
"TargetInstance.Drive = 'C:' AND " & _
"TargetInstance.Extension = 'txt' AND " & _
"TargetInstance.Path = '\\Test\\'")
Do
With oEvents.NextEvent()
s = "Event: " & .Path_.Class & vbCrLf
With .TargetInstance
s = s & "Name: " & .Name & vbCrLf
s = s & "File Size: " & .FileSize & vbCrLf
s = s & "Creation Date: " & .CreationDate & vbCrLf
s = s & "Last Modified: " & .LastModified & vbCrLf
s = s & "Last Accessed: " & .LastAccessed & vbCrLf
End With
If .Path_.Class = "__InstanceModificationEvent" Then
With .PreviousInstance
s = s & "Previous" & vbCrLf
s = s & "File Size: " & .FileSize & vbCrLf
s = s & "Last Modified: " & .LastModified & vbCrLf
End With
End If
End With
WScript.Echo s
Loop
The second is for asynchronous event processing:
Option Explicit
Dim oWMIService, oSink
Set oWMIService = GetObject("WinMgmts:\\.\root\CIMv2")
Set oSink = WScript.CreateObject("WbemScripting.SWbemSink", "Sink_")
oWMIService.ExecNotificationQueryAsync oSink, _
"SELECT * FROM __InstanceOperationEvent " & _
"WITHIN 1 WHERE " & _
"TargetInstance ISA 'CIM_DataFile' AND " & _
"TargetInstance.Drive = 'C:' AND " & _
"TargetInstance.Extension = 'txt' AND " & _
"TargetInstance.Path = '\\Test\\'"
Do
WScript.Sleep 1000
Loop
Sub Sink_OnObjectReady(oEvent, oContext)
Dim s
With oEvent
s = "Event: " & .Path_.Class & vbCrLf
With .TargetInstance
s = s & "Name: " & .Name & vbCrLf
s = s & "File Size: " & .FileSize & vbCrLf
s = s & "Creation Date: " & .CreationDate & vbCrLf
s = s & "Last Modified: " & .LastModified & vbCrLf
s = s & "Last Accessed: " & .LastAccessed & vbCrLf
End With
If .Path_.Class = "__InstanceModificationEvent" Then
With .PreviousInstance
s = s & "Previous" & vbCrLf
s = s & "File Size: " & .FileSize & vbCrLf
s = s & "Last Modified: " & .LastModified & vbCrLf
End With
End If
End With
WScript.Echo s
End Sub
More info on CIM_DataFile instance properties you can find by the link on MSDN.
As soon as the file is added to script folder it is detected by this code.
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
I want to execute VBScript as soon as it is added to script folder from this VBScript. How to do that? Getting the name of the file that is added to script folder and then executing that VBScript.
Replace this line of code with the code you want executed any time a new file is detected: Wscript.Echo objLatestEvent.TargetInstance.PartComponent. For instance, next code snippet shows a possible approach (and that's why there is wide Echo output, wider than necessary...):
''''(unchanged code above)
Do
Set objLatestEvent = colMonitoredEvents.NextEvent
''''Wscript.Echo objLatestEvent.TargetInstance.PartComponent
Call DoWithName( objLatestEvent.TargetInstance.PartComponent)
Loop
Sub DoWithName( strPartComp)
Dim arrFileName
arrFileName = Split( strPartComp, """")
If True Or UBound(arrFileName) > 0 Then
Wscript.Echo strPartComp _
& vbNewLine & UBound( arrFileName) _
& vbNewLine & "[" & arrFileName( 0) & "]" _
& vbNewLine & "[" & arrFileName( 1) & "]" _
& vbNewLine & "[" & arrFileName( 2) & "]" _
& vbNewLine & ShowAbsolutePath( arrFileName( 1))
End If
End Sub
Function ShowAbsolutePath( strPath)
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
ShowAbsolutePath = fso.GetAbsolutePathName( strPath)
End Function
Note that
the ShowAbsolutePath( arrFileName( 1)) returns the name of the file that is added to script folder; now you could
check whether it's a valid .vbs file name, and if so, launch it combining any Windows Script Host engine (wscript.exe or cscript.exe) in either
Run Method or
Exec Method.
You can try this modified script :
If AppPrevInstance() Then
MsgBox "There is an existing proceeding !" & VbCrLF &_
CommandLineLike(WScript.ScriptName),VbExclamation,"There is an existing proceeding !"
WScript.Quit
Else
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=""d:\\\\scripts""'")
Do
Set objLatestEvent = colMonitoredEvents.NextEvent
Call DoWithName(objLatestEvent.TargetInstance.PartComponent)
Loop
End if
' --------------------------------------
Sub DoWithName( strPartComp)
Dim Title,arrFileName,Question,ws
Title = "Execute vbscript"
set ws = CreateObject("wscript.shell")
arrFileName = Split( strPartComp, """")
If True Or UBound(arrFileName) > 0 Then
Wscript.Echo strPartComp _
& vbNewLine & UBound( arrFileName) _
& vbNewLine & "[" & arrFileName( 0) & "]" _
& vbNewLine & "[" & arrFileName( 1) & "]" _
& vbNewLine & "[" & arrFileName( 2) & "]" _
& vbNewLine & DblQuote(ShowAbsolutePath(arrFileName(1)))
End If
Question = MsgBox("Did you want to execute this vbscript : " & DblQuote(ShowAbsolutePath(arrFileName(1))),vbYesNo+vbQuestion,Title)
If Question = vbYes Then
ws.run DblQuote(ShowAbsolutePath(arrFileName(1)))
Else
End if
End Sub
' --------------------------------------
Function ShowAbsolutePath( strPath)
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
ShowAbsolutePath = fso.GetAbsolutePathName( strPath)
End Function
' --------------------------------------
Function DblQuote(Str)
DblQuote = Chr(34) & Str & Chr(34)
End Function
' --------------------------------------
Function CommandLineLike(ProcessPath)
ProcessPath = Replace(ProcessPath, "\", "\\")
CommandLineLike = "'%" & ProcessPath & "%'"
End Function
' --------------------------------------
Function AppPrevInstance()
With GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\.\root\cimv2")
With .ExecQuery("SELECT * FROM Win32_Process WHERE CommandLine LIKE " & CommandLineLike(WScript.ScriptFullName) & _
" AND CommandLine LIKE '%WScript%' OR CommandLine LIKE '%cscript%'")
AppPrevInstance = (.Count > 1)
End With
End With
End Function
' --------------------------------------
I want to get a unique id of a mouse provided that every mouse brand is the same in a laboratory.
I have tried using WMIC to get device attributes. My VBS script is this:
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_PointingDevice",,48)
Wscript.Echo "DeviceID: " & objItem.DeviceID
I have tried generating this script with different mouse brand and it outputs a unique device id. But when I use the same model/brand of mouse, the same device id is generated. Please help me find a unique data to be used to identify every mouse in a laboratory.
I think Thangadurai is right with his comment do your original question... However, you could try to find desired mouse id running next code snippets.
The simpliest solution with wmic:
wmic path Win32_PointingDevice get * /FORMAT:Textvaluelist.xsl
About the same output with vbScript: use cscript 28273913.vbs if saved as 28273913.vbs.
' VB Script Document
option explicit
' NameSpace: \root\CIMV2 Class : Win32_PointingDevice
' D:\VB_scripts_help\Scriptomatic
'
On Error GOTO 0
Dim arrComputers, strComputer, objWMIService, colItems, objItem
Dim strPowerManagementCapabilities
arrComputers = Array(".")
WScript.Echo "NameSpace: \root\CIMV2 Class : Win32_PointingDevice"
For Each strComputer In arrComputers
WScript.Echo "..."
WScript.Echo "=========================================="
WScript.Echo "Computer: " & strComputer
WScript.Echo "=========================================="
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_PointingDevice", "WQL", _
wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem In colItems
WScript.Echo "Availability: " & objItem.Availability
WScript.Echo "Caption: " & objItem.Caption
WScript.Echo "ConfigManagerErrorCode: " & objItem.ConfigManagerErrorCode
WScript.Echo "ConfigManagerUserConfig: " & objItem.ConfigManagerUserConfig
WScript.Echo "CreationClassName: " & objItem.CreationClassName
WScript.Echo "Description: " & objItem.Description
WScript.Echo "DeviceID: " & objItem.DeviceID
WScript.Echo "DeviceInterface: " & objItem.DeviceInterface
WScript.Echo "DoubleSpeedThreshold: " & objItem.DoubleSpeedThreshold
WScript.Echo "ErrorCleared: " & objItem.ErrorCleared
WScript.Echo "ErrorDescription: " & objItem.ErrorDescription
WScript.Echo "Handedness: " & objItem.Handedness
WScript.Echo "HardwareType: " & objItem.HardwareType
WScript.Echo "InfFileName: " & objItem.InfFileName
WScript.Echo "InfSection: " & objItem.InfSection
WScript.Echo "InstallDate: " & WMIDateStringToDate(objItem.InstallDate)
WScript.Echo "IsLocked: " & objItem.IsLocked
WScript.Echo "LastErrorCode: " & objItem.LastErrorCode
WScript.Echo "Manufacturer: " & objItem.Manufacturer
WScript.Echo "Name: " & objItem.Name
WScript.Echo "NumberOfButtons: " & objItem.NumberOfButtons
WScript.Echo "PNPDeviceID: " & objItem.PNPDeviceID
WScript.Echo "PointingType: " & objItem.PointingType
If Isnull( objItem.PowerManagementCapabilities) Then
strPowerManagementCapabilities=""
Else
strPowerManagementCapabilities=Join(objItem.PowerManagementCapabilities, ",")
End If
WScript.Echo "PowerManagementCapabilities: " & strPowerManagementCapabilities
WScript.Echo "PowerManagementSupported: " & objItem.PowerManagementSupported
WScript.Echo "QuadSpeedThreshold: " & objItem.QuadSpeedThreshold
WScript.Echo "Resolution: " & objItem.Resolution
WScript.Echo "SampleRate: " & objItem.SampleRate
WScript.Echo "Status: " & objItem.Status
WScript.Echo "StatusInfo: " & objItem.StatusInfo
WScript.Echo "Synch: " & objItem.Synch
WScript.Echo "SystemCreationClassName: " & objItem.SystemCreationClassName
WScript.Echo "SystemName: " & objItem.SystemName
WScript.Echo "."
Next
Next
Function WMIDateStringToDate(dtmDate)
WMIDateStringToDate = ( Left(dtmDate, 4) & "/" & _
Mid(dtmDate, 5, 2) & "/" & Mid(dtmDate, 7, 2) _
& " " & Mid (dtmDate, 9, 2) & ":" & Mid(dtmDate, 11, 2) & ":" & Mid(dtmDate,13, 2))
End Function
Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20
More complex than previous wmic example providing possibility to run it against more computers in one step. Note the arrComputers = Array(".") line. Here "." means This computer and could be rewritten by a list of computer names or IP addresses e.g.
arrComputers = Array _
( "computer_1_name" _
, "computer_2_IP" _
, "computer_3_name" _
)
how can i write vbscript that calculates the free space in C: drive of a windows machine
have a look at this page:
Set objWMIService = GetObject("winmgmts:")
Set objLogicalDisk = objWMIService.Get("Win32_LogicalDisk.DeviceID='c:'")
Wscript.Echo objLogicalDisk.FreeSpace
Set fso = CreateObject("Scripting.FileSystemObject")
Set d = fso.GetDrive("C:")
WScript.Echo d.FreeSpace
Use the FileSystemObject The page includes an JScript example
function ShowDriveInfo1(drvPath)
{
var fso, drv, s ="";
fso = new ActiveXObject("Scripting.FileSystemObject");
drv = fso.GetDrive(fso.GetDriveName(drvPath));
s += "Drive " + drvPath.toUpperCase()+ " - ";
s += drv.VolumeName + "<br>";
s += "Total Space: " + drv.TotalSize / 1024;
s += " Kb" + "<br>";
s += "Free Space: " + drv.FreeSpace / 1024;
s += " Kb" + "<br>";
Response.Write(s);
}
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_LogicalDisk where DeviceID='c:'",,48)
For Each objItem in colItems
if len(objItem.VolumeName)>0 then
Wscript.Echo "-----------------------------------" & vbCrLf _
& "VolumeName:" & vbTab & objItem.VolumeName & vbCrLf _
& "-----------------------------------" & vbCrLf _
& "FreeSpace:" & vbTab _
& FormatNumber((CDbl(objItem.FreeSpace)/1024/1024/1024)) & vbCrLf _
& "Size:" & vbTab & vbTab _
& FormatNumber((CDbl(objItem.Size)/1024/1024/1024)) & vbCrLf _
& "Occupied Space:" & vbTab _
& FormatNumber((CDbl(objItem.Size - objItem.FreeSpace)/1024/1024/1024))
end if
Next
I'm a beginner in VBscript and I got a script which obtains disk space usage of local drives. However, when some columns would contain long numeric value, some adjacent columns and even values are moving to the right and thus makes the output disorganized. I already
Please see below the contents of the script:
Option Explicit
const strComputer = "."
const strReport = "F:\dba_scripts\diskspace.txt"
Dim objWMIService, objItem, colItems
Dim strDriveType, strDiskSize, txt
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_LogicalDisk WHERE DriveType=3")
txt = "DRIVE" & vbtab & vbtab & "SIZE" & vbtab & vbtab & "USED" & vbtab & vbtab & "FREE" & vbtab & vbtab & "FREE(%)" & vbcrlf
For Each objItem in colItems
DIM pctFreeSpace,strFreeSpace,strusedSpace
pctFreeSpace = INT((objItem.FreeSpace / objItem.Size) * 1000)/10
strDiskSize = round((objItem.Size /1073741824),1) & " GB"
strFreeSpace = round((objItem.FreeSpace /1073741824),1) & " GB"
strUsedSpace = round(((objItem.Size-objItem.FreeSpace)/1073741824),1) & " GB"
txt = txt & objItem.Name & vbtab & vbtab & strDiskSize & vbtab & vbtab & strUsedSpace & vbTab & vbtab & strFreeSpace & vbtab & vbtab & pctFreeSpace & vbcrlf
Next
writeTextFile txt,strReport
wscript.echo "Report written to " & strReport & vbcrlf & vbcrlf & txt
' Procedure to write output to a text file
private sub writeTextFile(byval txt,byval strTextFilePath)
Dim objFSO,objTextFile
set objFSO = createobject("Scripting.FileSystemObject")
set objTextFile = objFSO.CreateTextFile(strTextFilePath)
objTextFile.Write(txt)
objTextFile.Close
SET objTextFile = nothing
end sub
The output file looks OK but when I send/email it using the free bmail, the results are disorganized (meaning some columns and values moved to the right.
My question is are there ways to make the columns and values results fixed ( meaning no columns and values are moving to the right )?
Function RightJustified(ColumnValue, ColumnWidth)
RightJustified = Space(ColumnWidth - Len(ColumnValue)) & ColumnValue
End Function
Usage example:
output = output & _
RightJustified(strDiskSize, 15) & _
RightJustified(strUsedSpace, 15) & _
RightJustified(strFreeSpace, 15) & _
RightJustified(pctFreeSpace, 15) & _
vbCrLf
EDIT
Add the RightJustified function to your script.
Then, replace this line of your code:
txt = txt & objItem.Name & vbtab & vbtab & strDiskSize & vbtab & vbtab & strUsedSpace & vbTab & vbtab & strFreeSpace & vbtab & vbtab & pctFreeSpace & vbcrlf
with:
txt = txt & objItem.Name & _
RightJustified(strDiskSize, 15) & _
RightJustified(strUsedSpace, 15) & _
RightJustified(strFreeSpace, 15) & _
RightJustified(pctFreeSpace, 15) & _
vbCrLf
EDIT 2
I added the RightJustified function at the bottom of your script, and then called it within your loop to format the columns. I also used it on the column headers. Below is the script and at the bottom is the output on my machine.
Option Explicit
const strComputer = "."
const strReport = "F:\dba_scripts\diskspace.txt"
Dim objWMIService, objItem, colItems
Dim strDriveType, strDiskSize, txt
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_LogicalDisk WHERE DriveType=3")
txt = RightJustified("DRIVE", 10) & _
RightJustified("SIZE", 15) & _
RightJustified("USED", 15) & _
RightJustified("FREE", 15) & _
RightJustified("FREE(%)", 15) & _
vbCrLf
For Each objItem in colItems
DIM pctFreeSpace,strFreeSpace,strusedSpace
pctFreeSpace = INT((objItem.FreeSpace / objItem.Size) * 1000)/10
strDiskSize = round((objItem.Size /1073741824),1) & " GB"
strFreeSpace = round((objItem.FreeSpace /1073741824),1) & " GB"
strUsedSpace = round(((objItem.Size-objItem.FreeSpace)/1073741824),1) & " GB"
txt = txt & _
RightJustified(objItem.Name, 10) & _
RightJustified(strDiskSize, 15) & _
RightJustified(strUsedSpace, 15) & _
RightJustified(strFreeSpace, 15) & _
RightJustified(pctFreeSpace, 15) & _
vbCrLf
Next
writeTextFile txt,strReport
wscript.echo "Report written to " & strReport & vbcrlf & vbcrlf & txt
' Procedure to write output to a text file
Sub writeTextFile(byval txt,byval strTextFilePath)
Dim objFSO,objTextFile
set objFSO = createobject("Scripting.FileSystemObject")
set objTextFile = objFSO.CreateTextFile(strTextFilePath)
objTextFile.Write(txt)
objTextFile.Close
Set objTextFile = nothing
End Sub
Function RightJustified(ColumnValue, ColumnWidth)
RightJustified = Space(ColumnWidth - Len(ColumnValue)) & ColumnValue
End Function
Output produced:
DRIVE SIZE USED FREE FREE(%)
C: 48.4 GB 40.6 GB 7.8 GB 16.1
D: 100.6 GB 56.8 GB 43.8 GB 43.5
You could write out a table using HTML. This should work in an email.