We run a nightly Robocopy job that backs up files from a directory on each user workstation to a server. Right now, we have to manually drop the hostnames into a text file, which is cumbersome to manage. I've written a VBScript that extracts the workstation names from Active directory, puts them in a recordset, and loops through a process of mapping a drive to each workstation, running the Robocopy job, and then cleaning up after itself. I've also included code to do some logging and create 0k files using Touch.exe that indicate whether or not a particular workstation has backed up successfully.
The part I'm having trouble with is the actual running of the Robocopy job. Here's the snippet of code code I'm using right now for that part of the job:
I've verified that strRobocopy creates a valid string, and when I run that string manually from a command prompt, the job runs without a hitch. But for some reason I can't figure out, the Robocopy job just hangs when it's called from my script. Sometimes it copies all the files successfully and then just doesn't quit, and other times it gets part of the way through the copying and stops. Sometimes it hangs when copying from different workstations; it's not always the same one that trips it up.
One interesting thing I've noticed is that when I'm running the script using the debugger and I check the value of objRobocopy.Status, and it returns nothing when I'm expecting a value of 0 or 1.
When I try executing the Robocopy job using the Run method, it runs just fine, but doesn't seem to return the exit codes I'm looking for so that my logging would work, although there's probably some way of extracting that from somewhere. I just don't know how I'd go about trying to obtain that data.
I've tried formatting this a few different way, using Do Until instead of Do While, trying different amounts of time for the VBScript to sleep, etc.,, but nothing's really solved the issue so far. Anybody out there have any ideas for other stuff I can try?
Well, we can help you with this, but before we do, I am a fan of not changing part of a process that works unless you have to. It sounds like your existing robocopy job works and the only real issue is the creation of the file that holds the host names. Why not just script that? Then you don't have to worry about running robocopy via script at all.
You know, I never really considered that. I just wanted to write a single script that did everything, I guess. It should be no trouble at all to write a script that dumps all the hostnames to the text file; in fact most of the code I'll need is already written from my work on this script.
All that said, I'd still like to figure this out if I can. I'm still kind of new to VB Scripting, so any opportunities to learn something are welcome.
.Exec will not give you access to the robocopy return code. What it does give you access to however is STDOUT. So you can parse STDOUT to see if the robocopy worked or not.
.Run does provide the return code. Could you post the command as you had it when you were doing .Run?
One other thing: could you provide me with an example of parsing STDOUT? I'm a little fuzzy on how to use the STDOUT, STDIN, and STDERR properties, or how to extract data from them.
Well, heck. That was exactly what I was trying to get it to do. Just goes to show that sometimes, another pair of eyeballs is all you need.
I had no idea that the line:
nReturn = objShell.Run(strRobocopy, 0, True)
would return the exit code and store it in the nReturn variable. I was under the impression that exit codes were always stored in the Err.Number property.
So next question: why does .Run perform this task flawlessly, but .Exec sputter? Is it something to do with Robocopy, or was it just me choosing the wrong tool for the job?
I'm not positive since .Exec worked for robocopy for me. Try grabbing the STDOUT from the robocopy and see if it gives any indication what is going on.
OK, I tried that, and Robocopy hung on the first workstation. So I commented out the While/Wend lines and put the script to sleep for 60 seconds, which is more than enough time needed for the Robocopy job to finish. I think that Robocopy terminated when the script resumed, and I got the Echo "ROBOCOPY STDOUT = ". It looks like it's returning a null, but I'm not sure if that's because Robocopy didn't terminate on its own, or because it's something screwy in the relationship between my script and Robocopy.
For each machine, the T: drive is mapped to \\hostname\c$\user box. And for this particular machine, it stops copying halfway through and just sits there. It's got to be something with the interplay between the Robocopy and the .Exec method because .Run works with no problem. I've tried this with a variety of combinations of Robocopy switches as well, but nothing seems to unstick it. I've also tried sharing this directory directly without going through the admin share, and that doesn't make any difference either.
Posts: 1924
Score: 16
Joined: 5/15/2003
From: USA
Status: offline
You might also want to have robocopy logging while it runs. I had a strange issue when trying to copy Visual Studio 2008 from the DVD to a network location and it would crap out on one file, happened on multiple Vista systems. Popped it into an xp system and it copied with no issues.
here is what I got in the log file, over and over until I killed RC.
OK, the more I dig into this, the more bizarre it gets.
I ran the script with the cmd \c at the beginning of my strRobocopy string. First, I tried it with the workstations in the same order as before, and I got the same result where it hung halfway through the job. So I selected a completely new handful of workstations to test this on, ran it, and it ran OK through the first workstation, and hung on the second workstation.
Out of curiosity, I decided to look and see if any of those files it was copying were in use, and there was a file in use by my user account (obviously, this is the file that it hung while copying). I looked at the file in the source directory, and it had a last modified timestamp of 8/4/2005 9:41 AM. I looked to see if the file showed up in the destination directory, and there it was, but with a last accessed timestamp of 1/1/1980 7:00 PM. No idea what to make of that.