VBScript to move file with wildcard, if it exists - vbscript

I am attempting to create a script that checks for the existence of archived eventlog files and, if any files exist, moves them to another folder. Running this script does nothing and gives no errors. I believe the wildcard in the If statement is what is giving me issues. I am new to vbscript, and scripting in general, and would appreciate some advice.
Set fso = CreateObject("Scripting.FileSystemObject")
If (fso.FileExists("d:\eventlogs\Archive*.evtx")) Then
FSO.CopyFile "d:\eventlogs\Archive*.evtx" , "d:\eventlogs\archive\"
FSO.Deletefile "d:\eventlogs\archive*.evtx"
End if

You can replicate a wild card search by using a combination of instr() and right(), or just multiple instr().
Set objFSO = CreateObject("Scripting.FileSystemObject")
objStartFolder = "d:\eventlogs\"
Set objFolder = objFSO.GetFolder(objStartFolder)
Set colFiles = objFolder.Files
For Each objFile in colFiles
if instr(objFile.Name,"Archive") <> 0 AND instr(objFile.Name,".evtx") <> 0 then
objFSO.MoveFile objFile.Name, "archive\" + objFile.Name
end if
Next

The appropriate approach of finding files with wildcards in VBScript:
Get the file collection from the containing folder
For each file in the filecollection:
Test the filename with a regular expression on a certain pattern
If the test passes, do some action with this file
Next file

Late answer, but might be useful because apparently nobody spotted the mistake.
From the VBScript documentation (script56.chm in my case), help page for CopyFile method says:
FileExists Method
Returns True if a specified file exists; False if it does
not.
object.FileExists(filespec)
Arguments
object
Required. Always the name of a FileSystemObject.
filespec
Required. The name of the file whose existence is to be determined. A complete path specification (either absolute or relative) must be provided if the file isn't expected to exist in the current folder.
Hence your expression fso.FileExists("d:\eventlogs\Archive*.evtx") returns False here; indeed there isn't any file named Archive*.evtx in your folder.
Either you remove your test, but you'll have to deal with the error the CopyFile method might generate, as doc says:
An error also occurs if a source using wildcard characters doesn't match any files.
As suggested by #automatedchaos in his answer https://stackoverflow.com/a/20907209/666414 you can also loop through files of the folder and decide what to do whenever the filename/extension matches your pattern.
Lastly, you can mix both solutions: loop through files of the folder, then set a flag to True and Exit Loop as soon as you encounter an expected file, then use the CopyFile method.
Like this:
With CreateObject("Scripting.FileSystemObject")
For Each objFile in .GetFolder("d:\eventlogs\").Files
If Left(objFile.Name, 7) = "Archive" And .GetExtensionName(objFile) = "evtx" Then
archiveFound = True
End If
Next
If archiveFound Then
.CopyFile "d:\eventlogs\Archive*.evtx", "d:\eventlogs\archive\"
.DeleteFile "d:\eventlogs\Archive*.evtx"
End If
End With
Note the wildcards work with the DeleteFile method too!

Related

How to get the basename when it gets truncated with period in path?

Am I missing a trick here?
Dim fso
Set fso = WScript.CreateObject("Scripting.FileSystemObject")
WScript.Echo fso.GetBaseName("D:\temp\1. Some Folder")
WScript.Echo fso.GetBaseName("D:\temp\Some Other Folder Without A Dot")
WScript.Echo fso.GetAbsolutePathName("D:\temp\1. Some Folder")
The code above for the basename gets truncated at the dot/period.
D:\temp\1
I'm assuming that VBScript is thrown by the dot. Is there a trick to getting around this? Or do you have to modify the full path after the last index of slash?
I believe GetFileName will produce the result you're looking for.
From the docs:
Returns the last component of a specified path that is not part of the drive specification.
The GetBaseName function indeed sees everything after the last dot as extension so the folder name you are expecting is truncated.
Safer, but only for existing paths could be to use the GetFolder function to receive a Folder object and take the Name property from that:
WScript.Echo fso.GetFolder("D:\temp\1. Some Folder").Name
returns
Some Folder

VBScript While file exists

This thing is going to kill me, or I'll kill it. I can't tell what I'm doing but I keep getting a file not found after I delete the file in a while statement.
MsgBox FSO.FileExists(file.path)'Returns True as a test
While (FSO.FileExists(file.path))
If objZip.Items.Item(0).Name = FSO.getfilename(file.path) Then
FSO.DeleteFile (file.path)
MsgBox FSO.FileExists(file.path)'Returns False as a test
End If
WScript.Sleep 100
Wend
Can someone point me to what I'm doing wrong? I have similar code in another working script.
When you delete the disk file the reference to it that is stored in the file variable is no longer valid. Store the file.Path value in a variable and change your code to use it.
Dim filePath
filePath = file.Path
While FSO.FileExists( filePath )
FSO.DeleteFile filePath
Wend
Note - Previous code just exposes the approach about how to reference the file. If DeleteFile fails (we are looping to remove the file) both error handling and loop wait are needed.

How do I search for a file extension located in the desktop and change their file types?

User = CreateObject("WScript.Network").UserName ' gets username
Set objFSO = CreateObject("Scripting.FileSystemObject")
Recurse objFSO.GetFolder("C:\Users\" & User & "\Desktop\") ' searches for file extensions in the desktop
Sub Recurse(objFolder)
Dim objFile, objSubFolder
For Each objFile In objFolder.Files
If LCase(objFSO.GetExtensionName(objFile.Name)) = "mymom" Then ' if a file extension is mymom (just a test)
objFSO.MoveFile objFile.Name objFile.Name & ".ayy" ' changes the file extension to ayy (another test)
End If
Next
End Sub
When I do this, I get an error saying, "Expected end of statement." However, I do not know where to add the end statement. What I am trying to do is I am trying to let the script search the Desktop for all files with a specific file extension (in this case, I want to search for a file extension with .mymom) Then, I want to change the file extension with .ayy (This is the struggle part) I don't know if my code is wrong, or if it's just the end statement part.
You are getting the error, probably because you have missed a , between the source and destination file paths in the moveFile method
Use this code:
strFinalName = replace(objFile.name, "."&objFso.getExtensionname(objFile.name),".ayy")
objFSO.MoveFile objFile.Name,strFinalName

File wont move to folder vbs

So im writing a script that drops a file folder then moves that file to the folder it dropped it self. Well the folder drops fine but the file wont move. Can some see whats wrong with my code? Or give me a better way to move the file. I also get no error message about trying to move the file.
Dim folder,fso,filsys,C
Set fso = CreateObject("Scripting.filesystemObject")
Set folder = fso.GetSpecialFolder(1)
Set wshshell = CreateObject("wscript.shell")
Set filesys = CreateObject("scripting.filesystemobject")
Set objfso = CreateObject("Scripting.filesystemObject")
Set c = fso.GetFile(Wscript.scriptFullname)
On Error Resume NEXT
Set objFolder = objFSO.CreateFolder("C:\55egr932ntn7mk23n124kv1053bmoss5")
If Err.Number<>0 Then
End If
WScript.Sleep 3000
C.Move ("C:\552ntn7mk23n124kv1053bmoss5\File.exe") (folder&"\File.exe")
And I have a program I use that turns the VBS into and EXE so you see the "file.exe" which really is the .VBS itself
I'm not familiar with this syntax, but the line below looks like it's expecting the folder variable to be a string.
C.Move ("C:\552ntn7mk23n124kv1053bmoss5\File.exe") (folder&"\File.exe")
Earlier in code it looks as though you're setting folder as an object.
Set folder = fso.GetSpecialFolder(1)
You might not get the error you mentioned in your comment if you convert folder to a string.
~~
Another thing to try is the following code:
Set fso = CreateObject("Scripting.filesystemObject")
Set folder = fso.GetSpecialFolder(1)
Alert (folder&"\File.exe")
(I'm not sure if it's "Alert" or "Msgbox" or something else.) That test will show you whether the file path makes sense. If you get an error on line 3 of that test, try converting folder to a string before your Alert (or Msgbox).

VBS: For-each loop (sometimes) iterates through file collection indefinitely

The goal of the following VBscript is to prepend a user-defined string to all files with a particular extension within a specified directory:
directory = "C:\Users\xxxxxxxx\Desktop\Test\" 'include final backslash
extension = ".doc" 'include period, ex: ".tab"
''''''''''''''''''''''''''''''''''''''''''
addStr = InputBox("Enter the text you would like to prepend:", , "xxxxxxxx_xxxxxxxxxx_x_xx_xxx_")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(directory)
Set colFiles = objFolder.Files
For Each file In colFiles
absPath = objFSO.GetAbsolutePathName(file)
currentExtension = objFSO.GetExtensionName(absPath)
If StrComp(currentExtension, Mid(extension, 2)) = 0 Then
file.Name = addStr & objFSO.GetFileName(file)
End If
Next
The script generally works well, but occasionally demonstrates this problematic behavior:
When running the script on a directory with lots of files and/or with files with long names, the script appears to iterate back over the collection of files (i.e. prepends to files that have already been prepended) and does so until the filenames become too long to be recognized by the FSO, crashing the script.
The threshold of the number of files/length of filenames at which this occurs appears to be very distinct and reproducible. For example, if I create a target directory (e.g. "...\Desktop\Test") with a file named '1.doc' that is copied/pasted several times, the script will properly rename up to 31 files, but it demonstrates the problematic behavior with 32+ files. Similarly, if I run the script twice over 31 files (generated in the same manner), the script demonstrates the problematic behavior on the second run.
Any thoughts as to the underlying issue are very much appreciated--thanks in advance!
You may have issues here because you're modifying files while iterating them. Try creating an array of file names first and then iterate over the array, changing the names.
ReDim a(colFiles.Count - 1)
i = 0
For Each File In colFiles
a(i) = File.Path
i = i + 1
Next
For i = 0 To UBound(a)
If StrComp(objFSO.GetExtensionName(a(i)), Mid(extension, 2)) = 0 Then
With objFSO.GetFile(a(i))
.Name = addStr & .Name
End With
End If
Next
The reason the above behaviour occurs is, because when you initially call Set colFiles = objFolder.Files, the first 32 files are retrieved, and placed into a cache. Once those 32 files are processed, then the system retrieves the first 32 filenames which have not been processed yet.
Since you have renamed the files after the initial call, the system sees those as new filenames that have not been processed yet. Since their names are still first alphabetically, they are placed into the 32-file cache, and processed again.
The solution by #Bond is the standard workaround for this issue. Due to limitations of vbs, this is the only practical resolution of this issue.

Resources