Solved

I am getting an error in a VB backup script

Posted on 2008-10-24
6
403 Views
Last Modified: 2012-08-30
On line 637 I get a "Path not found" error.  Any help figuring out this error would be greatly appreciated (and marked as such ;)
'**************************************************************
' Programmed by Michael Horowitz    michael@michaelhorowitz.com
' As of: August 30, 2002
' Version 2.11
'--------------------------------------------------------------
' Improved comments on defining sourcefolders array Oct 19,2005
' Added comments and notes on ERR object July 29, 2005
' Updated comments May 5, 2005 with a patch to send output to a
'   specific directory rather than root of a disk drive. Search
'   for the date of the change to find the comment.
' Updated comments January 14, 2005
' www.michaelhorowitz.com/backupscript.html
'**************************************************************
 
 
 
'**************************************************************
'      Controlling Parameters       (Configuration Variables)
'--------------------------------------------------------------
' These parameters control the operation of the script
' MODIFY them to suit your needs
'**************************************************************
 
'Output Drive letter. Backups are written to this drive
   OutputDrive = "E"
 
 
'Copy these folders to make a bkups of them
'Note: The number of array elements in the Dim statement is
'  always one less than the actual number of folders.
'  This is because VBScript arrays start at element zero.
'  For example:
'    dim sourcefolders(1) is used to back up 2 folders
'    dim sourcefolders(2) is used to back up 3 folders
'    dim sourcefolders(3) is used to back up 4 folders
'Another way to look at it is that the number in the dim
'  statement is the last element number
'The sample code below backs up three folders
   Dim objShell : Set objShell = CreateObject("Wscript.Shell")
  ProfilePath = objShell.ExpandEnvironmentStrings("%Userprofile%")
   dim sourcefolders(2)
   sourcefolders(0) = "C:\Outlook"
   sourcefolders(1) = ProfilePath & "\My Documents"
   sourcefolders(2) = ProfilePath & "\Desktop"
 
'Run in automated operation mode? (not case sensitive)
   AutoOpMode = "yes"         'Valid values are "yes" and "no"
 
'Minimum number of backup generations to keep
'(Only applies when AutoOpMode is "yes")
   MinBkupsToKeep = 3
 
'Minimum number of days to keep every backup generation
'(Only applies when AutoOpMode is "yes")
'If specifying zero, the script will not delete old generations created on the same
'day the script is run. A backup made today is considered zero days old and this
'field specifies the minimum age, in days, of backups that are to be kept.
   MinDaysToKeep = 8
 
'File name prefix for the log file and the main backup directory
'Use this to keep each set of folder backups separate and distinct
'from any other sets of folder backups.When applying the rules for
'automatically deleting old backups, only backups with the same
'value here are considered.
   OutputFilePrefix = "MikeBkup"
 
'A comment that is written to the log file
   LogComment = "Look ma, no hands!"
 
'Enable system logging?   (not case sensitive)
   SystemLogging = "no"   'Valid values are "yes" and "no"
 
'**************************************************************
'              End of controlling parameters
'**************************************************************
 
 
 
'-------------------------------------------------------------------------
'                        NOTES
'-------------------------------------------------------------------------
'Note to programmers: this is my first VBScript program and, as such, I made
'  some rookie mistakes. Also, it was coded using just the off-line Microsoft
'  documentation that comes with WSH when you download it. This doc is mostly
'  of a reference nature, there is not much in the way of a User Guide.
'  Specifically, variable names don't conform to any set standard.
'  I may have been a bit sloppy on variable scopes.
'  There is no error handling
'  I probably don't release all objects when I'm done with them. I do
'  release some, but added this after the fact.
'In manual mode, there is no constant status window on the screen while the
'  file copies are in progress. This is because I don't know how to do
'  this in WSH with VBScript. I'm pretty sure it's not even possible.
'  WSH was intended for non-interactive scripts.
'The NTFS file system supports compressed folders and files. WSH scripts
'  are not allowed to create new compressed directories. They also can not
'  change the compression attribute of an existing directory. As a result,
'  the only way to have this script create compressed backups under NTFS
'  is to have the entire drive compressed. If this gets to be a problem, the
'  script would have to be changed such that it no longer creates the main
'  backup directory in the root of the drive, but instead creates it under
'  a master, super compressed backup directory. It's do-able.
'It might be useful to put this script in a directory of its own for two
'  reasons. It keepts it segrated along with the log files and can avoid
'  mistakenly backing up the script while its running
'It might be useful to name the script with some ofthe parameters. For
'  example a copy that runs in auto-ops mode might be MikesBkupAuto.vbs.
'  Also daily backups might be called MikesBkupDaily while weekly
'  backups called MikesBkupWeekly.
'Windows 2000 users should consider backing up C:\WINNT\repair
'Worst to Best uses of this script:
' -Copy to the same hard disk as the source directories. If the hard
'      disk fails you lose the originals and the backups
' -Copy to a second hard disk on the same computer as the source files.
'      If the computer is damaged or lost, you lose originals and bkups
' -Copy to another computer on a LAN
' -Copy to an external hard disk connected to your computer either via
'    USB 1, USB 2.0, FireWire, pcmcia card or whatever
' -Copy to a USB based keychain storage device
' -Copy to a CD-RW disc (either on the same or different computer). This
'     allows removing the backup disc and storing it off-site. Note that
'     the max capacity of a CD-RW disc used this way is about 550 meg.
'     Requires use of Direct-CD software to initially format the CD-RW disc.
' -Copy to an on-line data storage. Only good if you have both a high speed
'     net connection and a backup service that appears to your computer as
'     just another disk drive.
' -Copy to a CD-R disc. As far as I know this is not possible without using
'     special software to write the files to the CD-R disc.
'When the log file says the script has finished, this is not completely true.
'  The log file is created in the directory that the script is running from.
'  After the log file is closed, it is copied to the main backup directory.
'  Needless to say,this final log copy should not be done with the log file
'  open. It can't audit activity on itself.
'There may be a bug in WSH v5.6. I have seen a network drive reported as using
'  the FAT file system when I'm pretty sure it was using FAT32. Local drives
'  that use FAT32 are correctly reported as doing so.
'There seems to be another bug in WSH v5.6. The operating system displays
'  as Windows_NT when running under Windows 2000.
 
 
'-----------------------------------------------------------------
'          INTRO --  WHAT THIS SCRIPT DOES
'-----------------------------------------------------------------
'This script backs up directories/folders. This script should be of use
'to people who need to back up files in multiple directories. You specify
'a list of directories to be backed up and the drive letter where the
'backups should reside. All the backups reside in a single backup
'directory. The name of the directory was chosen to make its purpose
'and creation date/time clear.
'
'Additional doc on this script is available on the web at:
'   www.michaelhorowitz.com/backupscript.html
'
'-----------------------------------------------------------------
'               DETAILED SPECS
'-----------------------------------------------------------------
'This script backs up directories (aka folders). It does not back
'  up individual files as I had no need for that. It backs up any
'  number of directories, each one has to be specified below as a
'  member of the sourcefolders array.
'This script logs its activity to a plain text log file. The log
'  file name is MikeBkup_Log_mmmdd.yyyy_hh.mm.txt. A copy of the
'  log is written to the directory the script is running out of.
'  An additional copy is written to the backup directory.
'All backed up directories reside in a single folder. The disk
'  drive where the folder is created is determined by the value
'  of the outputdrive variable. The directory name is
'  MikeBkup_Full_mmmdd.yyyy_hh.mm
'  Currently all backups are full backups, no incrementals.
'The backup is done using plain vanilla Windows file copy. No
'  special software is needed to view/use the backup files.
'With auto-operations mode OFF, before any copies are made
'  the user is presented with a message box
'  that shows the total number of bytes to be backed up and
'  the available free space on the output disk drive. It also shows
'  the output drive letter, its volume name and file system.
'  No backups are made until the user clicks Yes to this message.
'Even with auto-ops mode OFF, the user sees nothing while a
'  directory is being copied. After a directory has been copied,
'  a message is displayed for a couple seconds that shows the
'  directory name and the time taken to back it up.
'When all directories have been copied, the user is put into Notepad
'  to view the log file (if auto-ops mode is OFF)
'Directory names and structure are not perfectly preserved in the
'  backup copy, but this was done to make it easier to read.
'  For an explanation and example, see the doc on the web site.
'
'-----------------------------------------------------------------
'               BELLS AND WHISTLES
'-----------------------------------------------------------------
'After a folder has been copied, the total elapsed seconds for the
'  copy is calculated. If the copy took at least 4 seconds, then the
'  speed of the copy operation is calculated. Small directories are
'  ignored on purpose because the sample size is too small to produce
'  useful speed numbers. The speed of the backup is shown as both
'  bytes/second and MegaBits/second. The first number is useful as a
'  point of comparison when backing up from and to a local hard disk.
'  The second number is useful when backing up a computer on your LAN.
'  Are you really getting the 10 MegaBits/second the LAN was advertised
'  as being capable of? Probably not. Both these rates are externalized
'  in the log file.
'After copying all the source directories, the freespace on the output
'  disk drive is re-examined. This is done to compare the number of
'  bytes that should have been needed for the backup to the actual
'  number of bytes used. The bytes used is taken from the difference in
'  the amount of free space on the output drive before and after the copy
'  operation. This calculation gives you some idea of the wasted space
'  due to poor cluster sizes. This waste/overhead will vary depending on
'  the file system and the partition size. The worst case is a FAT
'  partition of 2 gigabytes. I once ran a copy of 219 Megabytes of data
'  to a disk drive that had 278 free Megabytes. The copy got only halfway
'  though before running out of space due to extreme cluster size waste.
'
'-----------------------------------------------------------------
'              The ERROR Object
'-----------------------------------------------------------------
'July 29, 2005. As noted on the web page for the script, its error handling
' is non-existant. These are my notes for when I get around to adding it.
'The Err Object has info on run-time errors, and can generate/clear them too.
'It has global scope - no need to create an instance of it
'Err.Number is an integer and can be used by an Automation object to return an SCODE.
'When a run-time error occurs, the properties of the Err object are filled with goodies
'The Raise method generates run-time errors
'All properties are reset to zero or zero-length strings after an On Error Resume Next
'The Clear method also resets it
'Example:
'  On Error Resume Next
'  Err.Raise 6   ' Raise an overflow error.
'  MsgBox ("Error # " & CStr(Err.Number) & " " & Err.Description)
'  Err.Clear
'msdn.microsoft.com/library/default.asp?url=/library/en-us/script56/
'   html/vtorierrobjectpropmeth.asp
 
 
 
'**************************************************************
'                    Common objects
'**************************************************************
 set fso = CreateObject("Scripting.FileSystemObject")
 Dim myNetworkObj
 Set myNetworkObj = Wscript.CreateObject("Wscript.Network")
 Dim TotalInputBytes   ' total size of all input folders
 TotalInputBytes = 0
 Set shellobj = CreateObject("Wscript.Shell")
 AutoOpMode = LCase(AutoOpMode)       'Force lower case
 SystemLogging = LCase(SystemLogging) 'Force lower case
 
 
'********************************************************************
'     Log the fact that the script started to the system log
'********************************************************************
 Dim temp   're-used alot but only with a short duration of validity
 temp = "Script: " & Wscript.Scriptname &" started"&vbCRLF& "Run by user: " &_
   myNetworkObj.UserName &vbCRLF& "From: " & Wscript.ScriptFullName &vbCRLF&_
   "Controlling Parameters: "               &vbCRLF&_
   "  AutoOpMode: "&       AutoOpMode       &vbCRLF&_
   "  OutputDrive: "&      OutputDrive      &vbCRLF&_
   "  OutputFilePrefix: "& OutputFilePrefix &vbCRLF&_
   "  MinBkupsToKeep: "&   MinBkupsToKeep   &vbCRLF&_
   "  MinDaysToKeep: "&    MinDaysToKeep    &vbCRLF&_
   "  SystemLogging: "&    SystemLogging    &vbCRLF&_
   "  Comment: "& LogComment
 If SystemLogging <> "no" Then
    ShellObj.LogEvent 4, temp  'Type four is an Informational message
 End If
 
 
'********************************************************************
'            Create the activity log file
' Its created in the directory where the script is running
' File name is  MikeBkup_Log_mmmdd.yyyy_hh.mm.txt
' The hours and minutes are putzed with so they are always 2 digits
'********************************************************************
 tempdate = now()
 dim filenamedate  'format is _mmmdd.yyyy_hh.mm
 filenamedate = MonthName(DatePart("m",tempdate), True) 'abbreviated month name
 filenamedate = "_" & filenamedate & DatePart ("d",tempdate) &_
      "." & DatePart ("yyyy",tempdate) & "_"
 temp = DatePart ("h",tempdate)
 If temp < 10 Then temp = "0" & temp
 filenamedate = filenamedate & temp & "."  'hour as hh
 temp =  DatePart ("n",tempdate)
 If temp < 10 Then temp = "0" & temp
 filenamedate = filenamedate & temp        'minutes as mm
 logfilename = OutputFilePrefix & "_Log" & filenamedate & ".txt"
 set logfileobj = fso.createtextfile(logfilename,true)
 
 
 '**************************************************************
 ' Write out some environmental information
 '**************************************************************
 logfileobj.WriteLine "*** Mike's backup script started at: " &now()& " ***"&vbCrLf
 logfileobj.WriteLine "Script: " & Wscript.Scriptname &"  Version 2.11 "
 logfileobj.WriteLine "Environment:"
 Set WshSysEnv = Shellobj.Environment("SYSTEM")
 logfileobj.WriteLine "  OS: " &   WshSysEnv("OS") &_
                      "  Computer: " & myNetworkObj.ComputerName &_
                      "  User: " &  myNetworkObj.UserName &_
                      "  WSH version: " & Wscript.Version
 set myNetworkObj = Nothing       ' let my object go
 Set WshSysEnv    = Nothing
 logfileobj.WriteLine "Running from: " & Wscript.ScriptFullName &" by "& Wscript.Application
 logfileobj.WriteLine "Comment: "  &  LogComment
 logfileobj.WriteLine "Controlling parameters:"
 logfileobj.WriteLine "  AutoOpMode="& AutoOpMode & " MinBkupsToKeep="& MinBkupsToKeep &_
                       " MinDaysToKeep=" & MinDaysToKeep &_
                       " OutputFilePrefix=" & OutputFilePrefix
 logfileobj.WriteLine "  OutputDrive=" & OutputDrive & " SystemLogging=" & SystemLogging
 
 
 
'**************************************************************
' Write out information about input folders
' Write each ones name and size to the log file
' Also log the total space needed to backup all input folders
'**************************************************************
  logfileobj.WriteLine "Input Folders to be copied:"
  Dim ifobj,indx2  ' Input Folder object, an index to the array
  For indx2 = 0 to UBound(sourcefolders, 1) 'fixed in v2.11, no more -1
    Set ifobj =  fso.GetFolder(sourcefolders(indx2))
    logfileobj.WriteLine "  "& sourcefolders(indx2) &" "&FormatNumber(ifobj.Size/1048576, 1)&" Megabytes"
    TotalInputBytes = TotalInputBytes + ifobj.Size
    Set ifobj = Nothing
  Next     'ifobj.Drive&"\"&ifobj.Name did not work well when copying from local dir
  Dim neededspace
  neededspace = FormatNumber(TotalInputBytes/1048576, 1) & " Megabytes"
  logfileobj.WriteLine "  Total size of input folders " & neededspace
 
 
'****************************************************************************
'             Chose an output disk drive
'                       and
'        Determine whether to make backups at all
'-----------------------------------------------------------------------------
'The following two routines set two important variables that are used later
'OutputDrive is the disk drive where the output backups are written
'ToCopyOrNotToCopy is the flag for whether to take backups or not
'It also has to set variables OutDrvObj and OutDrvFspc
'****************************************************************************
  Dim Drv,DrvType,DrvFspc,DrvTotSpc,DrvName,strDriveMsg,ToCopyOrNotToCopy
  Dim OutDrvObj     ' output drive object
  Dim OutDrvFspc    ' output drive freespace
'-----------------------------------------------------------------------------
' Chose output disk drive for manual mode
'   Show the user free space info on all available disk drives
'   Let user pick a drive letter  (default is config variable OutputDrive)
'   If user clicks Cancel button, then don't take any backups at all
'------------------------------------------------------------------------------
  If AutoOpMode <> "yes" Then   'manual mode
    logfileobj.WriteLine "Available disk drives:"
    For each Drv in fso.Drives
      If Drv.IsReady Then  'ignore drives that are not ready
        Select Case Drv.DriveType
            Case 0: DrvType = "Unknown"
            Case 1: DrvType = "Removable"
            Case 2: DrvType = "Fixed"
            Case 3: DrvType = "Network"
            Case 4: DrvType = "CD-ROM"
            Case 5: DrvType = "RAM Disk"
        End Select
        If Drv.DriveType=4 Then  'cdrom
 	  DrvFspc="N/A"
        ElseIf Drv.FreeSpace<1024^2 Then
	  DrvFspc=FormatNumber(Drv.FreeSpace/1024,0)&" KB"
        ElseIf Drv.FreeSpace<10240^2 Then
 	  DrvFspc=FormatNumber(Drv.FreeSpace/(1024^2),2)&" MB"
        Else
 	  DrvFspc=FormatNumber(Drv.FreeSpace/(1024^2),0)&" MB"
        End If
        If Drv.TotalSize<1024^2 Then
 	   DrvTotSpc=FormatNumber(Drv.TotalSize/1024,0)&" KB"
        ElseIf Drv.TotalSize<10240^2 Then
 	   DrvTotSpc=FormatNumber(Drv.TotalSize/(1024^2),2)&" MB"
        Else
 	   DrvTotSpc=FormatNumber(Drv.TotalSize/(1024^2),0)&" MB"
        End If
        If Drv.VolumeName="" Then
           DrvName="(None)"
        Else
           DrvName=Drv.VolumeName
        End If
        strDriveMsg=strDriveMsg&"Drive "& Drv.DriveLetter &_
 	   ": "&DrvName &vbTab &_
 	   "Free Space: " & DrvFspc &vbCRLF  'Build input box message
 	logfileobj.WriteLine "  "& Drv.DriveLetter &" - "& DrvName &" "&_
 	   " Free Space: " & DrvFspc  &" Total Space: "& DrvTotSpc &" " &_
 	   Drv.FileSystem &" "&DrvType
      End If
    Next 'next Drv in fso.Drives collection
    strDriveMsg="Space needed for backups: "& neededspace &vbCrLf&vbCrLf& strDriveMsg
    Dim InputDrive
    InputDrive = InputBox (strDriveMsg  &vbCRLF& "Enter desired output drive letter " &vbCRLF&_
       "  (enter a single character, no colon or slash) "  &vbCRLF&_
       "To skip backup entirely, click Cancel button", _
       "Select Output Disk Drive Letter", OutputDrive)
    If InputDrive = "" Then         'User clicked the Cancel button
         ToCopyOrNotToCopy = vbNo
    Else
         ToCopyOrNotToCopy = vbYes  'take the backups
         OutputDrive = InputDrive   'and use drive letter user input
         logfileobj.WriteLine "Backing up to -" & OutputDrive & "- drive per user input"
    End If
    Set OutDrvObj = fso.GetDrive(OutputDrive)   'output drive object
    OutDrvFspc = OutDrvObj.FreeSpace
  End If                            'End manual mode disk drive selection
'-----------------------------------------------------------------------------
' Chose output disk drive for AutoOps mode
'   Not much to chose, always use the value of config variable OutputDrive
'   Always make backups too (should eventually test if output drive has enough fspc
'   Log the total space available on this disk drive
'-----------------------------------------------------------------------------
   If AutoOpMode = "yes" Then
     ToCopyOrNotToCopy = vbYes   'In auto-op mode, always make a backup
     Set OutDrvObj = fso.GetDrive(OutputDrive)
     OutDrvFspc = OutDrvObj.FreeSpace
     logfileobj.WriteLine "Output drive: (from controlling parameter OutputDrive)"
     Select Case OutDrvObj.DriveType
        Case 0: DrvType = "Unknown"
        Case 1: DrvType = "Removable"
        Case 2: DrvType = "Fixed"
        Case 3: DrvType = "Network"
        Case 4: DrvType = "CD-ROM"
        Case 5: DrvType = "RAM Disk"
     End Select
     logfileobj.WriteLine "  " & OutputDrive & " " & OutDrvObj.VolumeName &_
        "(" & DrvType & ") " & OutDrvObj.FileSystem &" "& OutDrvObj.ShareName &_
        " Total Size: " & FormatNumber(OutDrvObj.TotalSize/1048576, 0) & " Megabytes" &_
        " Free Space: " & FormatNumber(OutDrvObj.FreeSpace/1048576, 1) & " Megabytes"
   End If    'End auto-ops mode disk drive selection
 
 
 
 '***************************************************************
 '             To Copy or Not To Copy
 '***************************************************************
 'Comment added May 5, 2005
 'Note: If you want to send the output backups to a folder rather than to the
 'root of the output disk drive, change the line below that assigns a value to
 'the outfoldername variable and add your desired folder name after the ":\"
 'For example:
 'outfoldername = OutputDrive & ":\MyBackups\" &  etc. etc.
 '---------------------------------------------------------------
  If ToCopyOrNotToCopy = vbNo Then       ' this was set by the code just above
    logfileobj.WriteLine vbCRLF & "BACKUP OPERATION BYPASSED BY USER"
  Else					 ' same variable used for the log file name/timestamp
    dim outfoldername                    ' date format is mmmdd.yyyy_hh.mm
    outfoldername = OutputDrive & ":\" & OutputFilePrefix & "_Full" & filenamedate
    set tempfolder = fso.CreateFolder(outfoldername)
    logfileobj.WriteLine "Created output folder " & tempfolder.Path
    set tempfolder = Nothing
    logfileobj.WriteLine "Copy starting..."
    Dim outfileobj
    CopyAllFolders()     'Do the copy!
  End If
 
 
'******************************************************************
'         Deal with backup generations
'******************************************************************
' Look for existing generations of backup folders on output Drive
' If NOT auto-op mode, tell the user this is happening
'------------------------------------------------------------------
  dim outmsg3, BkupGenCount
  logfileobj.WriteLine vbCrLf&"Searching for existing backup folders . . . "
  logfileobj.WriteLine "  looking in root of " & OutputDrive &_
                       " disk for directories starting with " & OutputFilePrefix
  If ToCopyOrNotToCopy = vbNo Then
      outmsg3 = "Backup operation BYPASSED" &vbCRLF& "Listing existing backup folders"
  Else
      outmsg3 = "Backup complete" &vbCRLF& "Searching for existing backup folders"
  End If
  If AutoOpMode <> "yes" Then
     shellobj.Popup outmsg3, 2, "Reviewing old backups . . ."
  End If
  BkupGenCount= 0                 'The number of backup generations found
  rootfold = OutDrvObj.RootFolder 'Root folder from output drive object
  CountBackups(rootfold)          'Count the number of backup generations and log them
 
 
'***********************************************************************
'    Accumulate all the existing backup generations into an array
'***********************************************************************
'This is done to aid in deleting the old generations
'Only do this in Auto-Op mode when there is more than one
'  generation of backups
'Accumulate the array, then sort it by the age of the backup,
'  then skip the first MinBkupsToKeep generations of backup.
'On whatever is left, see if it is older than MinDaysToKeep days.
'If yes, it's the weakest link. Goodbye.
'------------------------------------------------------------------
  If AutoOpMode<>"yes" Then
     logfileobj.WriteLine "Did not attempt to delete old backups because auto-op mode is off."
  ElseIf  BkupGenCount=0 Then
     logfileobj.WriteLine "Did not attempt to delete old backups because none were found."
  End If
  If (AutoOpMode<>"yes") or (BkupGenCount=0) Then
        BkupGenCount = BkupGenCount   'A fudged no-op
  Else
   Dim BkupGenerations()
   ReDim BkupGenerations(BkupGenCount-1)
   AccumBkupGens(rootfold)   ' Build array of all the existing backup generations
  '                 The array BkupGenerations is now fully populated, but unsorted
  '                 Next up: sort it by the age of each backup generation
  '                 Note: VBScript has no sort function,Jscript does.Had I only known.
   If BkupGenCount > 1 Then    'only sort if the array has at least 2 elements
      Dim outer, inner
      For outer = 0 to BkupGenCount-2      'from first element to next-to-last element
      For inner= outer+1 to BkupGenCount-1 'end at last array element
        If BkupGenerations(inner) < BkupGenerations(outer) Then 'switch them
            temp = BkupGenerations(inner)
            BkupGenerations(inner) = BkupGenerations(outer)
            BkupGenerations(outer) = temp
        End If
      Next
      Next
   End If
 '***********************************************************************
 '              Delete old backup generations
 '***********************************************************************
 'Are there more backup generations than the minimum required?
 '  If yes, start looking to prune them old backup generations
 'BkupGenerations array is now sorted by the age of the backup which is the
 '   first 4 characters of each elements
 'The newest backups are at the beginning of the array, so simply skiping the first
 '  MinBkupsToKeep elements of the array when looking to delete stuff will honor
 '  the directive to keep that many generations no matter what
 'The loop ends at the end of the BkupGenerations array
 'The loop starts with generation MinBkupsToKeep plus one
 'Vesion 2.6--added force option to DeleteFolder command. It uses a boolean value of
 '   True to indicate that force should be used.
 '----------------------------------------------------------------------------------
   If BkupGenCount > MinBkupsToKeep Then
      Dim indx, age4, forceit, DelCounter
      DelCounter = 0  'Count of deleted backup generations
      logfileobj.WriteLine "Examining old backups for possible deletion..."
      For indx = MinBkupsToKeep To BkupGenCount-1
        age4 = Left(BkupGenerations(indx),4) 'strip off the 4 digit age of bkup
        age4 = CLng(age4)                    'convert string to number (long)
        If age4 > MinDaysToKeep Then
           logfileobj.WriteLine "  Deleting " & Mid(BkupGenerations(indx),5) &_
                 " It is "& FormatNumber(age4,0) & " days old. Limit is " &_
                 MinDaysToKeep &" days"
           forceit = CBool(-1)  ' a TRUE boolean variable
           fso.DeleteFolder Mid(BkupGenerations(indx),5), forceit 'Delete backup folder
           DelCounter = DelCounter + 1   'Count of deleted backup generations
        End If
      Next
      logfileobj.WriteLine "Examination complete, "& DelCounter &" backup generations deleted."
   Else
      logfileobj.WriteLine "Did not attempt to delete old backups because minimum " &_
                           "generations not yet exceeded"
   End If
  End If
 
 
'**************************************************************
'                   Closing up shop
'**************************************************************
 logfileobj.WriteLine vbCrLf&"*** Mike's backup script ended at: " & now() & " ***"
 logfileobj.WriteLine        "   (Programmed by Michael Horowitz)"
 logfileobj.WriteLine        "   (www.michaelhorowitz.com/backupscript.html)"
 logfileobj.close   'close the log file
 Set logfileobj = Nothing
'If a backup was made, then copy the log file to the main output directory
 If (fso.FolderExists(outfoldername)) Then 'only copy if the folder exists
    If ToCopyOrNotToCopy = vbYes Then      'only copy if we made a backup
      Set logfileobj = fso.GetFile(logfilename)      'create a File object
      logfileobj.Copy(outfoldername&"\"&logfilename) 'copy log file to output directory
      Set logfileobj = Nothing
    End If
 End If
 
 
'********************************************************************
'                    Dat's All Folks
'If NOT auto-ops mode, then put the user in browse on the log file
'Log the fact that the script ended to the system log
'********************************************************************
 If AutoOpMode <> "yes" Then
     shellobj.Run "%windir%\notepad " & logfilename
 End If
 temp = "Script: " & Wscript.Scriptname &" ended"&vbCRLF&vbCRLF &_
    "Run from: " & Wscript.ScriptFullName
 If SystemLogging <> "no" Then
    ShellObj.LogEvent 4, temp  'Type four is an Informational message
 End If
'Wscript.Quit
 
 
'==============================================================
'==============================================================
'                SUBROUTINES
'==============================================================
'==============================================================
 
 
'**************************************************************
'  Copy all folders by looping thru the list of source folders
'**************************************************************
sub CopyAllFolders()
 Dim indx3  ' new in v2.10
 For indx3 = 0 to UBound(sourcefolders, 1) 'fixed in v2.11, no more -1
     copy1folder(sourcefolders(indx3))   ' GUTS of issue
 Next
'Below is the code that suffered from the bug fixed in v2.10
'For Each singleelement In sourcefolders
'    copy1folder(singleelement)
'Next
 logfileobj.WriteLine "Copy completed."   'Finished copying all folders
 Dim OutDrvFspcAfter
 OutDrvFspcAfter = OutDrvObj.FreeSpace
 logfileobj.WriteLine "Output Drive Freespace: Before " & FormatNumber(OutDrvFspc/1048576, 1) &_
     " After: " & FormatNumber(OutDrvFspcAfter/1048576, 1)
 logfileobj.WriteLine "Backups that should have used " & FormatNumber(TotalInputBytes/1048576, 1) &_
     " Megabytes, actually used " & FormatNumber((OutDrvFspc-OutDrvFspcAfter)/1048576, 1)  &_
     " Megabytes"
 If ((OutDrvFspc-OutDrvFspcAfter)-TotalInputBytes) > 5242880 Then '5 Megabytes=5242880
    logfileobj.WriteLine "   Note: look into cluster waste on " & OutDrvObj.FileSystem &_
    " " & OutputDrive & " drive"
 End If
end sub
 
'**************************************************************
'       Copy a single source folder to back it up
'**************************************************************
sub copy1folder(parm2)       'parameter looks like "C:\WINNT\repair"
  dim starttime, endtime, elapsecs, copytofolder, lenless3, tempfolder
  set thisFolder = fso.GetFolder(parm2)  'folder object for a source folder
  lenless3 = Len(parm2) - 3              'there is no substrng in vbscript
  copytofolder = Right(parm2,lenless3)   'strip off leading driveletter,colon,slash
  copytofolder = Replace(copytofolder, "\", "__" , 1, -1)  'replace slashes to force 1 level
  copytofolder = outfoldername & "\" & copytofolder
  set tempfolder = fso.CreateFolder(copytofolder)    'create the output bkup folder
  starttime = now()                        'Note when the copy started
  logfileobj.WriteLine " Start "&parm2&" "&starttime&" "&FormatNumber(thisFolder.size,0) & " bytes"
 
  thisFolder.Copy(copytofolder)            ' COPY!!
 
  endtime = now()                                  'Note when copy ended
  elapsecs = DateDiff("s", starttime, endtime)     'secs twixt start time and end time
  logfileobj.WriteLine "   End " & parm2 & " " & endtime & " " & elapsecs & " seconds to copy"
  If elapsecs > 3 Then         ' dont bother doing this for very small folders
    logfileobj.WriteLine "       Speed of copy: " & FormatNumber((thisFolder.size/elapsecs),0) &_
             " bytes/second "  &_
             FormatNumber((((thisFolder.size/elapsecs)*8)/1048576),1) & " MegaBits/second"
  End If
  Set thisFolder = Nothing
  Set tempfolder = Nothing
  If AutoOpMode <> "yes" Then     'Show user status if not in auto-ops mode
     shellobj.Popup "Copied "&parm2&" in "&elapsecs&" seconds", 3, "One Dir Down"
  End If
end sub
 
 
 
'*******************************************************************
' Loop thru the backups on the output disk drive a second time
'*******************************************************************
' Accumulate the backup generations in array BkupGenerations
' The array really should be two dimensional as it contains two data
'   items for each backup generation, the name and age. However, I
'   denormalized it into a single dimension array where each element
'   starts with a four digit age and is immediately followed by the
'   full name of the directory which contains the backup generation.
'   Its just easier to deal with this way, especially for sorting.
'   Sample array elements: 0012F:\somedir
'                          0002C:\otherdir
' Note: if there is ever a folder that is more than 9,999 days old
'   (27 years and change) this routine won't work correctly.
'   Waddya want for a free program.
'--------------------------------------------------------------------
sub AccumBkupGens(parm2)
  set thisFolder = fso.GetFolder(parm2)  'folder object
  set subfoldcol = thisFolder.SubFolders 'subfolder collection
  dim ArrayIndex, age, PrefixLen
  ArrayIndex = 0
  PrefixLen = Len(OutputFilePrefix)
  For each onefolder in subfoldcol
    If Len(onefolder.name)>PrefixLen and Left(onefolder.name,PrefixLen)=OutputFilePrefix Then
       age = DateDiff("d",onefolder.DateCreated,Now)
       If Len(age) = 1 Then age = "000" & age
       If Len(age) = 2 Then age = "00"  & age
       If Len(age) = 3 Then age = "0"   & age
       BkupGenerations(ArrayIndex) = age&onefolder.path
       ArrayIndex = ArrayIndex + 1
    End If
  Next
  set thisFolder = Nothing
  set subfoldcol = Nothing
end sub
 
'*************************************************************************************
' Count the number of backups that are on the output disk volume
' Pattern matched key used to be a folder starting with "MikeBkup_"
' Pattern matched key is now a folder starting with OutputFilePrefix
' This is done to Dim the array where they will be stored
' Also, write the name, size and creation date to the log file
'-----------
'Auto-deletion of old backup generations posed a technical problem. I wanted
'  to create an array with all the backups in it and apply the auto-delete
'  rules to the array. The problem was the VBScript does not allow arrays to
'  be dynamically sized. They are normally declared with a fixed number of
'  elements. That declaration can not be done with a variable, it must be
'  done with a numeric literal. It does allow sort-of dynamic arrays, that
'  are declared without a size. Before you can add elements to the array
'  however, you have to ReDim it with a fixed size. Luckily, the ReDim
'  statement takes a variable as input. However, this means I have to first
'  count every backup generation before I can store them in an array. I could
'  have declared the array with a large number of elements, but this is both
'  wasteful and an accident waiting to happen when there are too many elements.
'  moved this comment here January 14, 2005
'*************************************************************************************
 sub CountBackups(parm1)
     set thisFolder = fso.GetFolder(parm1)
     set subfoldcol = thisFolder.SubFolders
     Dim PrefixLen
     PrefixLen = Len(OutputFilePrefix)
     For each onefolder in subfoldcol
       If Len(onefolder.name)>PrefixLen and Left(onefolder.name,PrefixLen)=OutputFilePrefix Then
          BkupGenCount= BkupGenCount+ 1
          logfileobj.WriteLine "  "& onefolder.path & " (" &_
                FormatNumber(onefolder.Size/1048576, 1)&" Meg) "&onefolder.DateCreated
       End If
     Next
     set thisFolder = Nothing
     set subfoldcol = Nothing
     logfileobj.WriteLine "Search completed"
 end sub
 
'*******************************************************************
' Programmed by Michael Horowitz    michael@michaelhorowitz.com
'*******************************************************************

Open in new window

0
Comment
Question by:Corp616
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
6 Comments
 
LVL 67

Expert Comment

by:sirbounty
ID: 22797041
What does parm2 and copytofolder contain?

place a
msgbox parm2 & vbnewline & copytofolder

just prior to line 637...
0
 
LVL 1

Author Comment

by:Corp616
ID: 22797303
The script completes the copy of the outlook folder and reports the time elapsed.  It then starts the My Documents and appears to complete it but before it reports it complete with the time elapsed, I get the error on line 637.
0
 
LVL 1

Author Comment

by:Corp616
ID: 22797309
And I have no idea what parm2 or copytofolder contain, I did not write this script.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 67

Expert Comment

by:sirbounty
ID: 22797327
If you place this just before line 637:
msgbox parm2 & vbnewline & copytofolder

you can find out what it contains...
0
 
LVL 1

Author Comment

by:Corp616
ID: 22797523
The first message I get is:
C:\Outlook
E:\MikeBkup_Full_Oct24.2008_11.40\Outlook

followed by:
One Dir Down
Copied C:\Outlook in 0 seconds  **This directory is VERY small so the time does not suprise me**

The next messge is:

C:\Documents and Settings\CEBMPE\My Documents
E:\MikeBkup_Full_Oct24.2008_11.40\Documents and Settings_CEBMPE_My Documents

Then once the My Docs has finished copying (verified same on source and destination) but before any other messages appear, I get the error on line 637.
0
 
LVL 67

Accepted Solution

by:
sirbounty earned 500 total points
ID: 22797613
Well, your backup folder is already over 75 characters.  Depending on how many subfolders in your Docs & Settings, you could potentially be exceeding the 250 character limit for folder length?  
From the source computer, navigate through those folders to find the longest/deepest path - do any come close to that limitation?  Even close lengths may push this limit as the filenames contained therein may contribute to the length limitation as well...
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Deploying a Microsoft Access application in a Citrix environment is not difficult but takes a few steps. However, Citrix system people are often of little help, as they typically know next to nothing about Access. The script provided here will take …
With User Account Control (UAC) enabled in Windows 7, one needs to open an elevated Command Prompt in order to run scripts under administrative privileges. Although the elevated Command Prompt accomplishes the task, the question How to run as script…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…
How to Install VMware Tools in Red Hat Enterprise Linux 6.4 (RHEL 6.4) Step-by-Step Tutorial

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question