VBS - Transfer oldest file every 2 minutes - vbscript

I found some similar threads but they didn't solve the full problem i'm having, first, i'm a complete amatour when it comes to VBS, so i'm sorry if this is a simple problem.
I need to build a vbscript that transfers the oldest file from folder A to B every 2 minutes, this is what i come up with:
Dim colFiles
Dim strStartFolder
Dim strDestinationfolder
Dim oOldestFile
Dim oFile
Dim oFSO
strStartFolder = "C:\Users\lucas\Desktop\a\"
strDestinationfolder = "C:\Users\lucas\Desktop\b\"
I=0
Do While I=0
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set colFiles = oFSO.GetFolder(strStartFolder).Files
If colFiles.Count <= 1 Then
WScript.Quit
End If
For Each oFile In colFiles
If Not IsObject(oOldestFile) Then
Set oOldestFile = oFile
Else
If oFile.DateLastModified < oOldestFile.DateLastModified Then
Set oOldestFile = oFile
End If
End If
Next
Do While i=0
oOldestFile.Move strDestinationfolder & "\" & oOldestFile.Name
Wscript.Sleep (2000)
Loop
At the moment, the vbscript only tranfer the oldest file one time.
Can someone please help me with this ?
Thank you !
EDIT:
after the suggestions made by Hackoo and GJKH, the script looks like this :
Option Explicit
Dim colFiles
Dim strStartFolder
Dim strDestinationfolder
Dim oOldestFile
Dim oFile
Dim oFSO
strStartFolder = "C:\Users\lucas\Desktop\a\"
strDestinationfolder = "C:\Users\lucas\Desktop\b\"
Do
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set colFiles = oFSO.GetFolder(strStartFolder).Files
Wscript.echo colFiles.Count
For Each oFile In colFiles
If Not IsObject(oOldestFile) Then
Set oOldestFile = oFile
Else
If oFile.DateLastModified < oOldestFile.DateLastModified Then
Set oOldestFile = oFile
End If
End If
Next
oOldestFile.Move strDestinationfolder & "\" & oOldestFile.Name
' Pause 1 ' sleep for 2 minutes
Set oFSO = nothing
Set colFiles = nothing
Loop
'****************************************************************
Sub Pause(min)
wscript.sleep(min * 60 * 1000)
End Sub
'****************************************************************
He transfer the first file and than loops ( activated ECHO ) but he does not transfer any more files after the first one, any ideas ?

I know more about vb.net than vbs but a couple of things strike me as odd that may be causing problems here...
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set colFiles = oFSO.GetFolder(strStartFolder).Files
I would destroy these and recreate them each time it loops, in vb.net you would just set oFSO = nothing and colFiles = nothing, I'm sure the syntax is similar in vbscript.
If colFiles.Count <= 1 Then
WScript.Quit
I take it there is more than one file in the folder after you move the oldest one - because if not then script exits here.
Wscript.Sleep (2000)
This method parameter is in milliseconds, if you want to update every 2 minutes this will need to be Wscript.Sleep(120000), setting it to 2000 would be every 2 seconds.

Try like that :
Option Explicit
Dim colFiles
Dim strStartFolder
Dim strDestinationfolder
Dim oOldestFile
Dim oFile
Dim oFSO
strStartFolder = "C:\Users\lucas\Desktop\a\"
strDestinationfolder = "C:\Users\lucas\Desktop\b\"
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set colFiles = oFSO.GetFolder(strStartFolder).Files
'Wscript.echo colFiles.Count
Do
'Wscript.echo colFiles.Count
If colFiles.Count <= 1 Then
'Wscript.echo colFiles.Count
WScript.Quit
End If
For Each oFile In colFiles
If Not IsObject(oOldestFile) Then
Set oOldestFile = oFile
Else
If oFile.DateLastModified < oOldestFile.DateLastModified Then
Set oOldestFile = oFile
End If
End If
Next
oOldestFile.Move strDestinationfolder & "\" & oOldestFile.Name
Pause 2 ' sleep for 2 minutes
Loop
'****************************************************************
Sub Pause(min)
wscript.sleep(min * 60 * 1000)
End Sub
'****************************************************************

Related

Vbscript copy files based on beginning letters

I am trying to get this script to copy all files starting with "XX". Currently it only copies one file.
Dim objFSO, colFiles, objFile, strDestFolder, objNewestFile
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set colFiles = objFSO.GetFolder("C:\source")
strDestFolder = "C:\destination\"
For Each objFile In colFiles.Files
If Left(objFile.Name, 2) = "XX" Then
If objNewestFile = "" Then
Set objNewestFile = objFile
Else
If objNewestFile.DateLastModified < objFile.DateLastModified Then
Set objNewestFile = objFile
End If
End If
End If
Next
If Not objNewestFile Is Nothing Then
objFSO.CopyFile objNewestFile.Path,strDestFolder,True
End If
WScript.Echo "Copied."
You can use wildcards * and ? in [source] argument of FSO .CopyFile method.
So the code may look like:
Dim objFSO
Set objFSO = CreateObject("Scripting.FileSystemObject")
objFSO.CopyFile "C:\source\XX*.*", "C:\destination\", True
WScript.Echo "Copied."

Invalid Procedure call or argument when changing path

I tried to combine a couple different scripts, which works fine until I change the path of strPath. The moment I change it to anything else I get an error message
Invalid Procedure call or argument.
The script is meant to find the latest file in any directory (including subfolders), and copy and paste the file into a folder
Dim strPath, oFSO, oFile, oFolder, dteDate, strName, N
strPath = "C:\Users\parjo16\Documents\Archived"
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFolder = oFSO.GetFolder(strPath)
For Each oFile In oFolder.Files
If oFile.DateLastModified > dteDate Then
dteDate = oFile.DateLastModified
strName = oFile.Name
End If
N = N + 1
Next 'oFile
Call FindTheSubFolderFiles(oFolder, N, dteDate, strNme)
Const strfolder = "C:\SalaryData\"
Const Overwrite = True
Dim oFSOd
Set oFSOd = CreateObject("Scripting.FileSystemObject")
If Not oFSOd.FolderExists(strfolder) Then
oFSOd.CreateFolder strfolder
End If
oFSOd.CopyFile strNme, strfolder & "salaries.xlsx", Overwrite
Set oFSOd = Nothing
Set oFSO = Nothing
Set oFile = Nothing
Set oFolder = Nothing
Function FindTheSubFolderFiles(ByRef oParentFolder, ByRef lngR, ByRef dteDte, ByRef strNme)
Dim oSubFolder
Dim oFile
For Each oSubFolder In oParentFolder.SubFolders
For Each oFile In oSubFolder.Files
If oFile.DateLastModified > dteDte Then
dteDte = oFile.DateLastModified
strNme = oFile.Path
End If
lngR = lngR + 1
Next
FindTheSubFolderFiles oSubFolder, lngR, dteDte, strNme
Next 'oSubFolder
Set oSubFolder = Nothing
Set oFile = Nothing
End Function
Looks like the script was doing two checks, one for the main folder, one for the subfolder. If the result is the other, then it comes back blank.
This seems to be working now:
Function FindTheSubFolderFiles(ByRef oParentFolder, ByRef lngR, ByRef dteDte, ByRef strNme)
Dim oSubFolder
Dim oFile
For Each oSubFolder In oParentFolder.SubFolders
For Each oFile In oSubFolder.Files
If oFile.DateLastModified > dteDte Then
dteDte = oFile.DateLastModified
strNme = oFile.path
End If
lngR = lngR + 1
Next
FindTheSubFolderFiles oSubFolder, lngR, dteDte, strNme
Next 'oSubFolder
Set oSubFolder = Nothing
Set oFile = Nothing
End Function
Dim strPath, oFSO, oFile, oFolder, dteDate, strName, N
strPath = "C:\Users\parjo16\Documents\Archived\"
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFolder = oFSO.GetFolder(strPath)
For Each oFile In oFolder.Files
If oFile.DateLastModified > dteDate Then
dteDate = oFile.DateLastModified
strName = oFile.Name
End If
N = N + 1
Next 'oFile
Call FindTheSubFolderFiles(oFolder, N, dteDate, strNme)
Const strfolder = "C:\SalaryData\"
Const Overwrite = True
Dim oFSOd
Set oFSOd = CreateObject("Scripting.FileSystemObject")
If Not oFSOd.FolderExists(strfolder) Then
oFSOd.CreateFolder strfolder
End If
On Error Resume Next
oFSOd.CopyFile strPath & strName, strfolder & "salaries.xlsx", Overwrite
oFSOd.CopyFile strNme, strfolder & "salaries.xlsx", Overwrite
Set oFSOd = Nothing
Set oFSO = Nothing
Set oFile = Nothing
Set oFolder = Nothing

Asking for a little assistance with cleanup and error

I have been given a task of creating a script that takes a log file (date is in the filename), pulls the data and posts it in event manager. I have a script that works as it should I know the script is ugly so please be gentle. I'm looking for 2 things.
some days nothing has happened and no log for the day was created. when this happens my script causes all kinds of slowness in the PC. I need help with a way for the script to not do its task if no new file has been added to the logs folder.
I would like a little help cleaning up the script.
Like i said i'm very new to this and i used scripts found on the web and fit them to do what i needed them to do.
any help would be greatly appricated.
Option Explicit
Const ForReading = 1
Dim strfolder
Dim FSO
Dim FLD
Dim fil
Dim strOldName
Dim strNewName
Dim strFileParts
Dim objShell
Dim objFSO
Dim objFolder
Dim strFileName
Dim objFile
Dim objTextFile
Dim strNextLine
Dim arrServiceList
Dim i
strFolder = "C:\Logs\"
Set objShell = CreateObject ("Wscript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(strFolder)
Set objShell = CreateObject ("Wscript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile ("C:\Logs\logCatchAll.log", ForReading)
For Each strFileName in objFolder.Items
If len(objFSO.GetExtensionName(strFileName)) > 0 Then
Set objFile = objFSO.GetFile(strFolder & strFileName.Name)
If DateDiff("H",objFile.DateLastModified,Now()) > 24 Then
objFSO.DeleteFile(strFolder & strFileName.Name),True
End If
End If
next
Set FSO = CreateObject("Scripting.FileSystemObject")
Set FLD = FSO.GetFolder(strfolder)
For Each fil in FLD.Files
strOldName = fil.Path
If InStr(strOldName, "-") > 0 Then
strFileParts = Split(strOldName, "-")
strNewName = strFileParts(0) & ".log"
FSO.MoveFile strOldName, strNewName
End If
Next
Set FLD = Nothing
Set FSO = Nothing
Do Until objTextFile.AtEndOfStream
strNextLine = objTextFile.Readline
arrServiceList = Split(strNextLine , ",")
For i = 3 to Ubound(arrServiceList)
objshell.LogEvent 4, arrServiceList(i)
Loop
You can block your Dim'd variables
You are reactivating the objShell to many times
You have a for loop at the bottom of your code without a Next statement.
You don't need to iterate through the log file until it reaches AtEndOfStream, just store it in a variable first.
You can use the same objFSO more than once if your not resetting the object.
You need to include error handling so you know where your code breaks.
Revised code.
Option Explicit
'Handle errors manually.
On Error Resume Next
'Set Constants
Const ForReading = 1
'Set Strings
Dim strFolder, strOldName, strNewName, strFileName, strFileParts, strNextLine, TFStrings
strFolder = "C:\Logs\"
'Set Objects
Dim objShell, objFSO, objFolder, objFile, objTextFile
Set objShell = CreateObject ("Wscript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objShell.Namespace(strFolder)
TFStrings = split(objFSO.OpenTextFile("C:\Logs\logCatchAll.log", ForReading).ReadAll, vbcrlf)
'Set Other Variables
Dim FLD, fil, arrServiceList, i, executed
executed = false
'Delete file procedure...
For Each strFileName in objFolder.Items
If len(objFSO.GetExtensionName(strFileName)) > 0 Then
Set objFile = objFSO.GetFile(strFolder & strFileName.Name)
If DateDiff("H",objFile.DateLastModified,Now()) > 24 Then
objFSO.DeleteFile(strFolder & strFileName.Name),True
executed = true
End If
End If
Next
If executed then
If err.number <> 0 then
'File was found, but delete was unsuccessful, log failure of delete.
executed = false
err.clear
Else
'Delete file procedure executed successfully. Lets move on.
executed = false
End If
Else
'No file was found within the conditions. log failure of search.
End if
'Move file and rename procedure...
Set FLD = objFSO.GetFolder(strfolder)
For Each fil in FLD.Files
strOldName = fil.Path
If InStr(strOldName, "-") > 0 Then
strFileParts = Split(strOldName, "-")
strNewName = strFileParts(0) & ".log"
objFSO.MoveFile strOldName, strNewName
executed = true
End If
Next
Set FLD = Nothing
Set FSO = Nothing
If executed then
If err.number <> 0 then
'File was found, but move was unsuccessful, log failure of move.
executed = false
err.clear
Else
'Move file procedure executed successfully. Lets move on.
executed = false
End If
Else
'No file was found within the conditions. log failure of search.
End if
For Each line in TFStrings
strNextLine = line
arrServiceList = Split(strNextLine , ",")
For i = 3 to Ubound(arrServiceList)
objshell.LogEvent 4, arrServiceList(i)
Next
Next

Do I need a wait time for setting a new folder vbs?

I am using the following code:
Set StorageFileSystem = CreateObject("Scripting.fileSystemObject")
Set StorageFolder = StorageFileSystem.GetFolder(PathToStorageFiles)
msgBox "Set folders for Storage"
for each Storagefile in StorageFolder.Files 'get the creation time of the oldest recording
msgBox "DateCreated: " & Storagefile.DateCreated & vbCrLf & "EarylDateTime: " & earlyDateTime & vbCrLf & "DateTime to compare: " & dateadd("h" ,-6, Now)
if Storagefile.DateCreated < dateadd("h" ,-6, Now) then
earlyDateTime = Storagefile.DateCreated
end if
next
I have used this before without problem, even in the program that this is in. However this time it never seems to do anything. The folder has over 130,000 files in it (391GB). I don't know if I should include a delay so that the program can emumerate them or if there is some other problem that I just don't see.
Any ideas? I'm using VBS, the msgBox between the 2 set statements and the for loop works, but the one between the opening of the for loop and the if statement does not.
Are you saying the codes in the For loop doesn't seem to work? It seems not work if the folder does not have any files in it. So check the value of PathToStorageFiles.
Your logic of getting the oldest recording creation time is flawed - any time that is 6 hours before Now is treated as oldest and set to earlyDateTime.
Try this code below, with sample output:
PathToStorageFiles = "C:\Test" ' <=- Change this!
Set StorageFileSystem = CreateObject("Scripting.fileSystemObject")
Set StorageFolder = StorageFileSystem.GetFolder(PathToStorageFiles)
sOldestFile = "" ' Stores the full name of the file
earlyDateTime = dateadd("h" ,-6, Now) ' Assuming 6 hours before script started is oldest (it can be just Now)
wscript.echo StorageFolder.Files.Count & " files in the folder " & PathToStorageFiles
for each Storagefile in StorageFolder.Files 'get the creation time of the oldest recording
if Storagefile.DateCreated < earlyDateTime then
sOldestFile = Storagefile.Path
earlyDateTime = Storagefile.DateCreated
wscript.echo "earlyDateTime changed to " & earlyDateTime & " | " & sOldestFile
end if
next
wscript.echo vbCrLf & "Oldest file: " & sOldestFile & vbCrLf & "Created on: " & earlyDateTime
On a side note, you should modify this to process sub folders too, then move files into folders. 130,000 files in a single folder is a mess!
UPDATE
Based on your posted solution, there are improvements you can do.
First, use 1 FileSystemObject.
Then the recentFile in the for loop. You should set it to zero first, rather than 2 comparisons. Having said that, you have the opportunity to time the differences.
recentFile = 0
For Each file in colFiles
If file.DateCreated > recentFile Then
recentFile = file.DateCreated
End If
Next
Lastly, if the D: on the server is a NAS, then you can split the code into 2 parts - one search for most recent, the other for oldest. Then use batch file start cscript.exe //nologo <script#.vbs> method to start them in 2 processes. This you need 2 txt files for output.
If there is only 1 folder to get the latest & oldest file, it can be in 1 for loop.
This is the code that I got to work:
Option Explicit
Dim LocalStorage, NewLocalStorage, recentFile, objFSO, colFiles, objFolder, file, OldestDate, strOldestDate, fso, ts, objFile
LocalStorage = "D:\BlueIris\Storage"
NewLocalStorage = "D:\BlueIris\New"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(NewLocalStorage)
Set colFiles = objFolder.Files
For Each file in colFiles
If recentFile = "" Then
recentFile = file.DateCreated
ElseIf file.DateCreated > recentFile Then
recentFile = file.DateCreated
End If
Next
Set objFolder = objFSO.GetFolder(LocalStorage)
Set colFiles = objFolder.Files
OldestDate = Now
For Each objFile in colFiles
if objFile.DateCreated < OldestDate Then
OldestDate = objFile.DateCreated
strOldestDate = objFile.DateCreated
End if
Next
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.CreateTextFile ("C:\DVRInfo.txt", true)
ts.writeline recentFile
ts.writeline strOldestDate
ts.close
I run this on the actual server so that it runs a lot faster than the original code I attempted. Let me know if you still flaws in this please, I want to be as efficient as possible.
Thanks
EDIT:
New code:
Option Explicit
Dim LocalStorage, NewLocalStorage, recentFile, objFSO, colFiles, objFolder, file, OldestDate, strOldestDate, fso, ts, objFile
LocalStorage = "D:\BlueIris\Storage"
NewLocalStorage = "D:\BlueIris\New"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(NewLocalStorage)
Set colFiles = objFolder.Files
Set recentFile = 0
For Each file in colFiles
If file.DateCreated > recentFile Then
recentFile = file.DateCreated
End If
Next
Set objFolder = objFSO.GetFolder(LocalStorage)
Set colFiles = objFolder.Files
OldestDate = Now
For Each objFile in colFiles
if objFile.DateCreated < OldestDate Then
OldestDate = objFile.DateCreated
strOldestDate = objFile.DateCreated
End if
Next
Set ts = fso.CreateTextFile ("C:\DVRInfo.txt", true)
ts.writeline recentFile
ts.writeline strOldestDate
ts.close

How can I make script for recursive downloading all empty files?

I need to develop the VBScript that donwload all files with size equals 0 from drive C. I have made following script:
Dim oFSO
Dim sDirectoryPath
Dim oFolder
Dim oFileCollection
Dim oFile
Dim oFolderCollection
Dim n
Set oFSO = CreateObject("Scripting.FileSystemObject")
sDirectoryPath = "C:\"
set oFolder = oFSO.GetFolder(sDirectoryPath)
set oFolderCollection = oFolder.SubFolders
set oFileCollection = oFolder.Files
For each oFile in oFileCollection
IF oFile.Size = 0 Then
oFile.Delete(true)
END IF
Next
But this script deletes files from root directory of drive C only! I need to use recusrive in this code, but I'm new in VBScript and don't know how I can do it. Please, I hope you will help me. Thank you.
here a tested and working script
set oFso = createobject("scripting.filesystemobject")
sDirectorypath = "c:\testing"
delete_empty_files(sDirectorypath)
sub delete_empty_files(folder)
set oFolder = oFso.getfolder(folder)
for each oFile in oFolder.files
if oFile.size = 0 then
wscript.echo " deleting " & oFile.path
oFile.delete(true)
end if
next
for each oSubFolder in oFolder.subfolders
delete_empty_files(oSubFolder)
next
end sub

Resources