I am trying to write a script to delete unneeded temporary files. I am wanting to specifically target .tmp's, though. At least for now. So I am trying to write a WQL query to return a collection with which I can use a FOR EACH statement to delete all of the .tmp's in C:\Users\\AppData\Local\Temp. I've only recently started learning VBScript. But I have experience writing programs in C/C++ (mainly "math-y" programs).
Cscript seems to have no problem with the query itself. But when I try to use the Count method on the resulting collection, cscript returns an error: (17,1) Microsoft VBVScript runtime error: Object doesn't support this property or method: 'colTempFiles.Count'.
I've read up on WQL a little bit, thinking that maybe I'm not getting a collection returned for some reason. But I can't seem to find anything wrong with the query. I'm thinking that maybe I shouldn't be selecting from FileSystemObject. But I've read what I can find about it, and it seems to be the right thing to do (although there really isn't a lot of helpful info on MSDN).
Anyway, here's the script I currently have, without comments. The second line is something I am not currently using, but am going to try to use later, so that I can define a variable as the local computer's username and not have to point to the local Temp folder's path specifically. Any help would be greatly appreciated:
strComputer = "."
strUser="adam"
Set objFSO=CreateObject("Scripting.FileSystemObject")
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colTempFiles = objWMIService.ExecQuery _
("SELECT * FROM FileSystemObject WHERE Name = '*.tmp' AND "_
& "NOT Name LIKE 'Prf%' AND Path LIKE 'C:\Users\adam\AppData\Local\Temp\%'")
colTempFiles.Count
For Each objFile in colTempFiles
Wscript.Echo objFile.Name
'Set objF=objFSO.GetFile("objFile.Path")
'objF.Delete(True)
Next
I think you're confusing two different technologies. A FileSystemObject is a COM class that needs to be instantiated using CreateObject() in VBScript. For WQL, you need to use a WMI class in your query. Here is a core list of WMI classes. For your purposes, you'll want to use the CIM_DataFile class to work with files.
You can use either technology. The FileSystemObject is the preferred method if you're working with the local file system. If you need to work with files on a remote machine, use WMI and WQL.
Here's an example using a FileSystemObject:
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder("C:\Users\adam\AppData\Local\Temp")
For Each objFile In objFolder.Files
If StrComp(objFSO.GetExtensionName(objFile.Path), "tmp", vbTextCompare) = 0 Then
objFile.Delete ' This is the Delete() method of the FSO's "File" class
End If
Next
And here's an example using WQL:
strComputer = "."
' Connect to the WMI service on the specified computer...
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
' Build our WQL query...
strQuery = "select * from CIM_DataFile "
strQuery = strQuery & "where Drive='C:' "
strQuery = strQuery & "and Path='\\Users\\adam\\AppData\\Local\\Temp\\' "
strQuery = strQuery & "and Name like '%.tmp'"
' Run the query...
Set colTempFiles = objWMIService.ExecQuery(strQuery)
' Delete each file...
For Each objFile In colTempFiles
objFile.Delete ' This is the Delete() method of the WMI "CIM_DataFile" class
Next
Related
I have a Server with multiple Sessions on it, which all have to have a process running.
My Program should start up that process as soon as it stopped and the Session is online.
I checked for the process, and if I didn't find it I just started it. The problem is, I see the same process over all Sessions. How can I just get the processes of my Session and not the whole Server's?
This was my try, but it throws me an Error:
option explicit
DIM strComputer
DIM strProcessName
DIM WshShell
DIM strWMIQuery
DIM strSessionID
Set wshShell = CreateObject("WScript.Shell")
strSessionID= wshShell.ExpandEnvironmentStrings("%SESSIONID%")
strComputer = "."
strProcessName = "FortiSwitch-Replacer.exe"
strWMIQuery = "Select * from Win32_Process where name like '" & strProcessName & "' AND SessionId like '" & strSessionID & "'"
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
if objWMIService.ExecQuery(strWMIQuery).Count > 0 then
'Dont do anything
else
'start process
end if
The Error is at the "ExecQuery()" Part (line 18) saying "Invalid query"
Lankymart found out the Answer:
The SessionId needs to be an Integer while mine was a String. By Changing the Value into an Integer the program would've worked.
What I want to add:
The ExpandEnvironmentStrings don't offer the SessionId. Right now I've used a small script from an Answer of this Question: Is it possible to run Powershell code from VBScript?
It Runs the simple Powershell command to get the SessionId in VBS.
If anyone else has some different Ideas on how to get the SessionId another way I'm interested to learn and see them :)
Im looking for some help with creating a script that can scan the Disk Drives on a Server or PC and search out a Zepto Virus infection and alert us in our Monitoring Dashboard.
We have used scripts to detect Cryptowall and Locky but these rely on searching for a very specific file name. The difference with Zepto is that its "Help" files are composed with a random number in each file:
_3_HELP_instructions.html, _21_HELP_instructions.html, _12_HELP_instructions.html etc.
Essentially im looking for a script that can maybe search for *_HELP_instructions.html or even just search for any filename with HELP_instructions.html contained in it.
The code we have used for Locky is as follows:
strComputer = "."
set objFSO = CreateObject("Scripting.FileSystemObject")
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colShares = objWMIService.ExecQuery("Select * from Win32_Share")
For each objShare in colShares
strInfected = False
If objFSO.fileexists(objShare.path & "\_Locky_recover_instructions.txt") then
strInfected = True
wscript.echo "Network Share " & objShare.Path & " is INFECTED!"
wscript.quit(2015)
End If
Next
If strInfected = False Then
wscript.echo "System Clear!"
wscript.quit(0)
End If
Is there anyone out there that can help me with this one? due to the way our Monitoring Dashboard works i need the script to be based on the above, with the:
If strInfected = False Then
wscript.echo "System Clear!"
wscript.quit(0)
End If
at the end of the script.
Many thanks in advance
I have the following script which locates all access files on a machine:
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colFiles = objWMIService.ExecQuery _
("Select * from CIM_DataFile Where Extension = 'mdb' OR Extension = 'ldb'")
For Each objFile in colFiles
Wscript.Echo objFile.Name
Next
I'm very amateur when it comes to vbscript. Instead of Echoing to a dialog box, how do I have the script write each line out to a text file called "Results.txt"?
Also, as a bonus, how do I include the date modified of each Access file?
This is what you are looking for. In this part: ("C:\test.txt" ,8 , True), the first parameter is the path to the file. The second parameter is the iomode option. There are three options for the second parameter, 1 means for reading, 2 means for writing, and 8 means for appending. The third parameter is a boolean, true means a new file can be created if it doesn't exist. False means a new file cannot be created.
Dim FSO
Set FSO = CreateObject("Scripting.FileSystemObject")
Set OutPutFile = FSO.OpenTextFile("C:\test.txt" ,8 , True)
OutPutFile.WriteLine("Writing text to a file")
Set FSO= Nothing
Simple Google search like "vbscript create and write to text file" will give you ocean of information on how to tackle this. Anyway here is simplest one to give you kick start.
'~ Create a FileSystemObject
Set objFSO=CreateObject("Scripting.FileSystemObject")
'~ Provide file path
outFile="YouFolderPath\Results.txt"
'~ Setting up file to write
Set objFile = objFSO.CreateTextFile(outFile,True)
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colFiles = objWMIService.ExecQuery _
("Select * from CIM_DataFile Where Extension = 'mdb' OR Extension = 'ldb'")
For Each obj_File in colFiles
'Wscript.Echo objFile.Name 'Commented out
'~ Write to file
objFile.WriteLine obj_File.Name
Next
'~ Close the file
objFile.Close
Use the FileSystemObject's .CreateTextFile method to create a text file. Study the documentation/sample carefully.
A CIM_DataFile has a .LastAccess property.
I am pulling results back from WMI using WQL via VBScript.
In examples, a For Each loop is used to iterate over the results, but in each example, it is assumed that the property names are known. Case in point:
Set colInstalledPrinters = objWMIService.ExecQuery ("Select * from Win32_Printer Where Default = True")
For Each objPrinter in colInstalledPrinters
Wscript.Echo objPrinter.Name
Next
Some of the WMI classes have a very long list of properties associated with them. As an additional complication, some properties cannot be expected to be present (according to various webpages I have read about WMI). Rather than researching each WMI class and hoping that the properties listed are present, I would like to obtain a list of the properties (or columns, if I am thinking in SQL/WQL) present for, say, an objPrinter or any other returned item.
Python is my usual language but I cannot install it on the target machines in this instance; I can perform remote querying of WMI via Python but I am trying to trigger on an local event, hence falling back to VBScript. Although I gather Powershell might be able to do this, I would rather not learn it just this instant.
So, does VBScript support that level of introspection which would allow me to enumerate a list of properties? Or is there something I can do involving a schema I can reference and examine in-script?
Use the .Properties_ collection of the item:
Option Explicit
Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20
Dim objWMIService
Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")
Dim colItems
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_Printer" _
, "WQL" _
, wbemFlagReturnImmediately + wbemFlagForwardOnly _
)
Dim objItem
For Each objItem In colItems
Dim oProp
For Each oProp In objItem.Properties_
WScript.Echo oProp.Name, TypeName( oProp.Value ), ToString( oProp.Value )
Next
WScript.Echo
Next
Function ToString( vX )
ToString = "!! work to do !!"
On Error Resume Next
ToString = CStr( vX )
On Error GoTo 0
End Function
Output:
...
MimeTypesSupported Null !! work to do !!
Name String Auto HP LaserJet 5 on WINXP2
NaturalLanguagesSupported Null !! work to do !!
Network Boolean False
PaperSizesSupported Variant() !! work to do !!
...
Obviously, the ToString() function needs further work.
I am using the following VBScript code snippet to enumerate all files in my c:\Scripts\ folder:
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colFiles = objWMIService. _
ExecQuery("Select * from CIM_DataFile where Path = '\\Scripts\\'")
For Each objFile in colFiles
Wscript.Echo objFile.Name
Next
Unfortunately objFile.Name returns the path in all lower-case. It is important to me to retrieve the case of all file names, i.e. NewFileOne.txt, should not be returned as newfileone.txt.
Is there a way to enumerate files with case-sensitivity in VBScript?
If you use the FileSystemObject, you will get back names with the case preserved
Files Collection (MSDN)
dim objFSO, path, fldr, f, msg
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set fldr = objFSO.GetFolder("C:\Scripts")
For Each f in fldr.Files
MsgBox f.name
Next
Unlike the CIM_DataFile.Name property, the FileName and Extension properties are case sensitive. So, if it's necessary for you to use WMI, you can retrieve the file name and extension separately:
WScript.Echo objFile.FileName & "." & objFile.Extension
Mike's solution is better, but here's A VERY UGLY alternative:
Using the shell exec execute the following command:
dir c:\scripts /B>file.txt
Now "file.txt" contains the file listed with proper casing.
Sorry, it's ugly but works.