VbScript copying Files & deleting from source

Im creating a script to copy files from one directory to another, checking  that the files have copied then delete the files from the source. Id like to create an Event Log of failed and successful transfers.

Ive created the below which goes as far as Mapping 2 drives first check to see if that drive is mapped if so disconnects it then maps it. I know i could call the shell and use something like xcopy to move the files but id much rather prefer to use all vbscript. Could someone help me out? I know i can create a objShell.LogEvent but am unsure on how to tie it to failed sending or successful sending. Im quite new to VBscripting and have learnt everything i do know pretty much from Experts exchange. So any help would be great ;)





Dim objNetwork, objFSO
Dim strDriveLetterTo, strTransTo, strUser, strPassword, strPer, strDriveLetterFrom, strTransFrom, strFile, WSHShell

Set objNetwork = CreateObject("WScript.Network")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set WSHShell = CreateObject("Wscript.Shell")

strDriveLetterFrom = "X:"
strTransFrom = "\\SHARHERE\Inbound"
strDriveLetterTo = "Y:"
strTransTo = "\\SHAREHERE\Outbound"
strUser = "Username"
strPassword = "Password"
strPer = "False"
strFile ="*.*"

If objFSO.DriveExists(strDriveLetterTo) = True Then
   objNetwork.RemoveNetworkDrive strDriveLetterTo
End If

If objFSO.DriveExists(strDriveLetterFrom) = True Then
   objNetwork.RemoveNetworkDrive strDriveLetterFrom
End If

objNetwork.MapNetworkDrive strDriveLetterFrom, strTransFrom

objNetwork.MapNetworkDrive strDriveLetterTo, strTransTo, strPer, strUser, strPassword

Open in new window

k3eperAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

sgdoughtCommented:
Here's what I use to copy to all servers in a list of servers

On Error Resume Next
Const ForRead = 1    'Opens file for reading
Const ForWriting = 2 'Opens file for writing, overwriting file
Const ForAppend = 8  'Opens file for Appending
strComputer = "."    ' This computer
DriveLetter = "Q:" 'Set Constant to drive letter  To change all occurances
               'of the DriveLetter in the script simply change the constant

Const OverwriteExisting = True
Const NoOverWrite = False


' Open the input File
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\d'sdata\work_jeffco\myservers.txt", ForRead)
Err.Clear
Set ResultsFile=objFSO.OpenTextFile("C:\temp\results.txt", ForWriting )
If Err.Number <>0 Then
     Wscript.Echo "The results file could not be opened"
     Wscript.Echo "The errror number is " & Err.Number
     Wscript.Echo "The error message is " & Err.Message
End If
Wscript.Sleep 5000

Do Until objFile.AtEndOfStream
     'Read line from input file
     ServerOU = objFile.ReadLine
     Wscript.Echo "OU is " & ServerOU
     
     'Read the next line of input file
     ServerUNC = objfile.ReadLine
     WScript.Echo  "Echo Server UNC is " & ServerUNC

     ' Create Network object
     Set objNetwork = Wscript.CreateObject("Wscript.Network")

     ' Map the network drive to the UNC, if already mapped remove first
     objNetwork.RemoveNetworkDrive DriveLetter
     WScript.Echo "Mapping Drive....."
     WScript.Echo
     objNetwork.MapNetworkDrive DriveLetter, (ServerUNC  & "zen")
     If Err.Number <> 0 Then
        ResultsFile.WriteLine "Server UNC is " & ServerUNC
        ResultsFile.WriteLine ServerOU & " " & Err.Description
        Err.Clear
        ResultsFile.WriteLine
     End If
   

     Set colDrives = objNetwork.EnumNetworkDrives
     For i = 0 to colDrives.Count-1 Step 2
        Wscript.Echo colDrives.Item (i) & vbtab & colDrives.Item (i+1)
     next

     
     'copy files to the current server
     Err.Clear
     If objFSO.FolderExists ("Q:\snapshot")  Then
          objFSO.CopyFolder "c:\d'sdata\Office Updates" , "Q:\snapshot\Office Updates" , OverwriteExisting
         
          If Err.Number = 0 Then
                 ResultsFile.WriteLine "Office Updates copied to " & ServerOU
            Else
               ResultsFile.WriteLine "Office Updates  did not copy to " & ServerOU
          End If
     Else
          Err.Clear
          If objFSO.FolderExists ("Q:\snapshots")  Then
               objFSO.CopyFile "c:\d'sdata\Office Updates" , "Q:\snapshots\Office Updates" , OverwriteExisting
         
               If Err.Number = 0 Then
                           ResultsFile.WriteLine "Office Updates copied to " & ServerOU
                    Else
                         ResultsFile.WriteLine "Office Updates  did not copy to " & ServerOU
               End If
          End If      
      End If      
     Err.Clear
 
 
Loop





'Cleanup
objNetwork.RemoveNetworkDrive "Q:"
objNetwork.RemoveNetworkDrive "Z:"
objfile.Close
ResultsFile.close
k3eperAuthor Commented:
Hmm its not quite what im looking for as its reading lines from text and copying directorys. Im looking to copy(move) all files from one directory to another then check files have copied correctly then delete files from source. thanks for the response tho.  I did get a hint of what i need to google for now tho "objFSO" seems to hold the keys to the copying and most likley the checking of the files.
sgdoughtCommented:
Yes.  If objFile.FileExists is where you need to go to check for existence.

Also objFile.DeleteFile, objFSO.DeleteFolder, etc.
Starting with Angular 5

Learn the essential features and functions of the popular JavaScript framework for building mobile, desktop and web applications.

sgdoughtCommented:
objFSO.Move also for file and folder.

See this link for moving files:
http://technet.microsoft.com/en-us/library/ee198719.aspx

The scripting guide is VERY helpful.
k3eperAuthor Commented:
Brilliant thank you ive got it moving to the filedesination, now i need to try work out how to check the destination for files copied in this transaction. Maybe assing something to the properties of the file? then check the files for the properties if they exsits delete the source files? Or maybe check files moved on the current date?
k3eperAuthor Commented:
Had another idea, objFSO.GetFileName I could check the files in the directory capture them somehow into a variable then copy all files to destination then check the destination for all files that are in source. If all there delete from source. How would i capture the ouput into a variable?
Bill PrewIT / Software Engineering ConsultantCommented:
Why not just use the objFSO.Move command, and check for error after it executes for each file?  That way if it copies fine it will automatically delete the source file.  If it fails to copy the file it shouldn't delete it.

~bp
k3eperAuthor Commented:
Bp thats a much better idea, simpler and more efficient. So If Error move to whatever line (line to move file again?)
sgdoughtCommented:
Err.clear
If err.number <> 0 then
sgdoughtCommented:
Err.clear
If err.number <> 0 then
WScript.Echo "There was an error moving file"
WSCript.Echo "The error was " & Err.Description.
End if


k3eperAuthor Commented:
This script will be executed when called by a service account. so echos would need to be captured into event logs or such. Is that possible?
Bill PrewIT / Software Engineering ConsultantCommented:
Sure, rather that Echo just write the lines to a file of your choice, something like:

Const ForAppending = 8
strLog = "Log.txt"

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(strLog, ForAppending, True)
 
objFile.WriteLine "Line 1"
objFile.WriteLine "Line 2"

objFile.Close

the other approach would be to use the wscript.echo approach, and when you run the script redirect the output of the cscript command to a log file, something like:

cscript //nologo test.vbs >log.txt

~bp
sgdoughtCommented:
If you want to write to an event log you can use eventCreate as in this sample:

Shell ("eventcreate /t information /id 998 /l Application /d Starting_Shutdown_Application"
k3eperAuthor Commented:
Is there a way i could use objShell.LogEvent "Somehow get the details in here?"
Bill PrewIT / Software Engineering ConsultantCommented:
objShell.LogEvent will write an entry into the application event log in Windows, if that's what you are after?

~bp
k3eperAuthor Commented:
Ok im getting somewhere. Ive got the below working quite well just not liking the format it comes out in. Is there a way to create a break in the line so the next txt line goes the lines below like so:

Error:
Source:
Description:

at the mo its like so

Error: 58 Source: Microsoft VBScript runtime error Desciption: File already exists
If Err.Number <> 0 Then
	WScript.Echo "Error: " & Err.Number
	WScript.Echo "Source: " & Err.Source
	WScript.Echo "Desciption: " & Err.Description
WSHShell.LogEvent Error_Log, "Error: " & Err.Number & " Source: " & Err.Source & " Desciption: " & Err.Description & " FileSource: " & strTransFrom
End If

Open in new window

Bill PrewIT / Software Engineering ConsultantCommented:
Not sure if this will work, but you could try:

If Err.Number <> 0 Then
        WScript.Echo "Error: " & Err.Number
        WScript.Echo "Source: " & Err.Source
        WScript.Echo "Desciption: " & Err.Description
WSHShell.LogEvent Error_Log, "Error: " & Err.Number & vbCrLf & " Source: " & Err.Source & vbCrLf & " Desciption: " & Err.Description & vbCrLf & " FileSource: " & strTransFrom
End If

~bp
k3eperAuthor Commented:
vbCrLf did the job perfectly thanks ;), now to the next step of what id like to do.
k3eperAuthor Commented:
Ok objFSO.GetFileName, how can i search a directory for all file names and ext and input that into either mem space (variable) or into a txt file. So i can then check both directorys. If dest has the file already delete from source.

Or another method(prefered but has issues). Use objFSO.MoveFile if already exsists then overwrite. There doesnt seem to be a way to overwrite files with MoveFile. So the above was the next best method.
sgdoughtCommented:
objFso = server.createObject("Scripting.FileSystemObject")
objFile = objFso.getFile(strLocation1)

objFile.Move(strLocation2, true)
k3eperAuthor Commented:
The true statement doesnt work with MoveFile. Doesnt the above code mean the same as;

Set objFSO = CreateObject("Scripting.FileSystemObject")


objFSO.FileMove(strLocation2) True

?
sgdoughtCommented:
you are correct.  From MSDN:
Okay, what we just said isn’t entirely true. Other than the obvious fact that Move moves and Copy copies, there’s one big difference between these methods that you need to know about. While the Copy method accepts a second parameter that determines whether or not an existing file is overwritten - with a default of True - the Move method doesn’t accept any other parameters. Not only that, but the default, and, in this case, the only behavior is just the opposite. If you run the script we just showed you and the file test.txt already exists in C:\scripts\temp, the file will not be moved and you’ll receive an error message:

Copy Code

C:\scripts\test.vbs(4, 1) Microsoft VBScript runtime error: File already exists
k3eperAuthor Commented:
:( wish i wasnt. Ok so ill have to do something abit more complecated.

Id like to

'strFileSource is in fact X:\*.csv for instance.

If objFSO.FileExists(strFileSource)  Then maybe store the results into a txt file? so i can then check:
'strFileDest is for instance Y:\
If objFSO.FileExists(strFileDest) compare the lists. Hmmm might just be simpler to FileCopy True to overwrite, then move the source files to an archive folder incase?

I need to make sure the files are moved to the destination if they are deleted and not moved or are corrupted some how, it could have impact on the business. Could i have some thoughts, maybe ideas of best doing i what i need?
Bill PrewIT / Software Engineering ConsultantCommented:
In my humble opinion, you really should look at using a robust utility for this, like RoboCopy.  It can handle all the error checking and file replacement and log any errors, etc.  I really don't see value in trying to rebuild that type of logic in VBS if you don't have to.

That being said, you could get around the Move not overwriting by just checking if the dest file already exists and if so delete it before the Move command.

If not, then you have to do a Copy, and then decide how you want to validate that the dest file contents exactly match the source file, before deleting it.  Again, I'd still encourage you to use a utility that can handle that type of stuff, especially if your business depends on the accuracy of the copy.

~bp

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
sgdoughtCommented:
I'd agree with going with Robocopy.  I use it all the time at my schools.   Dang, I shoulda thought of that.
k3eperAuthor Commented:
Ok ill go wih the Robocopy option. I will still need to create a script in vb to call the robo copy.cmd as ill need to run it with a service account sooo...... does this look correct?
k3eperAuthor Commented:

Dim objNetwork, objFSO
Dim strUser, strPassword, strScript

Set objNetwork = CreateObject("WScript.Network")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set WSHShell = CreateObject("Wscript.Shell")
set strScript = "C:\RoboScript.cmd"


strUser = "Username"
strPassword = "Password"

WSHShell.Run strScript, 0

Open in new window

k3eperAuthor Commented:
Oops no Set on the set strScript = "C:\RoboScript.cmd" line.
k3eperAuthor Commented:
hmm just had a thought that doesnt actualy call the username and pass. How would i use them?
sgdoughtCommented:
Are you running the script as a logon script?   Then you do not need topass the user name and password.   you only need to pass them if you are trying to get a script to run on a remote host (which i have never managed to make work since SP2 added the firewall).
sgdoughtCommented:
You need to download the server tools to get a copy of robocopy.  
k3eperAuthor Commented:
Hi sorry about the delay, has been rather mental.

Ok I have roboCopy and have created a cmd script accordinly. But to call that script im using vbs to map drives etc to the shares etc that need the data transfering to and from. Simple enough right?

Well i am now getting 80020005 Type Mismatch: access denied. Even tho if i manually map the drives using the account in question it works fine. Code is attached below, any thoughts would be appreciated.


Dim objNetwork, objFSO
Dim strDriveLTo, strTransTo, strUser, strPassword, strPer, strDriveLFrom, strTransFrom, WSHShell, strScript

Const Error_Log = 1

Set objNetwork = CreateObject("WScript.Network")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set WSHShell = CreateObject("Wscript.Shell")


strDriveLFrom = "X:"
strTransFrom = "\\Server\Share\"
strDriveLTo = "Z:"
strTransTo = "\\Server\Share"
strUser = "Domain\username"     'Have tried domian/username and just username
strPassword = "password"
strPer = "False"
strScript = "C:\Scripts\InfoSecMove.cmd"


'On Error Resume Next

If objFSO.DriveExists(strDriveLetterTo) = True Then
   objNetwork.RemoveNetworkDrive strDriveLetterTo
End If

If objFSO.DriveExists(strDriveLetterFrom) = True Then
   objNetwork.RemoveNetworkDrive strDriveLetterFrom
End If


'objNetwork.MapNetworkDrive strDriveLTo, strTransTo, strUser, strPassword

objNetwork.MapNetworkDrive strDriveLFrom, strTransFrom, strUser, strPassword

'WSHShell.Run strScript, 0

Open in new window

Bill PrewIT / Software Engineering ConsultantCommented:
What line # does the error occur on?

~bp
k3eperAuthor Commented:
Line 34

sgdoughtCommented:
I think you need to use unc oaths, not "x:"   Try sticking with one format.
k3eperAuthor Commented:
ok so saying dont bother mapping the drives, just copy directly to the unc's?

Ill give it ago thanks.
k3eperAuthor Commented:
Hmm but how do i copy the files across using a particular account if i dont map the drives with that account?
k3eperAuthor Commented:
Grr how anoying. I thought id use Net User \\unc\share pass user
then Robocopy .....unc path etc
then net use \\unc\share /delete

but im still getting bloody access denied in the robo script

2010/10/28 13:09:26 ERROR 5 (0x00000005) Accessing Source Directory \\server\share\folder\
Access is denied.
k3eperAuthor Commented:
Sigh funny how something so simple can turn into a nightmare. Script below im getting "System error 67 has occurred" before the denies code below for the robo cmd that is called by the vbs.

@ECHO

Set User=/USER:Domain\User
Set Pass=password

Net Use \\server\share\folder1 %pass% %user% 
Net Use \\server\share\folder2 %pass% %user%


robocopy \\server\share\folder1 \\server\share\folder2 *.* /V /FP /COPY:DAT /MOV /Z /NP /R:10 /W:30

Net Use \\server\share\folder1 /Delete
Net Use \\server\share\folder2 /Delete

Open in new window

Bill PrewIT / Software Engineering ConsultantCommented:
Try this format:

Net Use \\server\share\folder1 /USER:%user% %pass%

~bp
Bill PrewIT / Software Engineering ConsultantCommented:
Actually, you can't map to a folder under a share, only to the share itself.

Net Use \\server\share /USER:%user% %pass%

~bp
k3eperAuthor Commented:
Ok altered it to the below but still getting the 67 Error
@ECHO

Set User=/USER:Domain\User
Set Pass=password

Net Use \\server\share %pass% %user% ' Tried moving user and pass round same error both times

robocopy \\server\share\folder1 \\server\share\folder2 *.* /V /FP /COPY:DAT /MOV /Z /NP /R:10 /W:30

Net Use \\server\share\ /Delete

Open in new window

k3eperAuthor Commented:
Ok ive got the script working now, but have come across another problem.

This script will be launched automaticly when files are dumped into a folder by a ftp process therefore the script is lauched on a server that doesnt have anyone logged into it.

If it is run by double clicking it when someone is logged in it works fine and as expected. but if no one is logged in it doesnt work.
k3eperAuthor Commented:
Any ideas?
sgdoughtCommented:
You could write as a vb6 app (close to vbscript, but slightly different), then run it as a service with srvany, set the service start up to automatic,  but that is a totally different topic for another day.
k3eperAuthor Commented:
:( ive got a support call open with the system that would kick off the script initially as it has services that should start it off. Thanks for all the help chaps i think i can close this Question.
k3eperAuthor Commented:
Brilliant thanks Guys
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
VB Script

From novice to tech pro — start learning today.