16223 Letture

Automatizzare il backup del contenuto di qualunque cartella con uno script VBS

Per effettuare il backup automatico del contenuto di alcune cartelle memorizzate sul disco fisso vi sono, com'è noto, numerose metodologie: è possibile affidarsi all'utilità di Windows, utilizzare programmi "ad hoc" sviluppati da terze parti oppure servirsi di appositi script in grado di sovrintendere l'intera procedura.

Questa volta vi proponiamo uno script VBS, realizzato dalla redazione de IlSoftware.it, che consente di creare una copia del contenuto delle directory indicate dall'utente attraverso la modifica di un file di configurazione (config.ini). Il nostro script provvede a "leggere" il contenuto del file .INI in modo da stabilire quali cartelle debbono essere oggetto di backup nel caso del sistema in uso.

Per ciascuna macchina presente nella propria infrastruttura, si possono specificare le cartelle il cui contenuto deve essere messo in sicurezza (ad esempio, salvato in un'unità rimovibile).


Lo script VBS s'incarica di creare automaticamente una cartella col nome identico a quello assegnato alla macchina in uso. Tale denominazione corrisponde a quella che compare cliccando con il tasto destro destro sull'icona Computer, in Windows Vista così come in Windows 7, quindi sulla voce Proprietà:

In Windows XP, è il nome che può essere rilevato cliccando con il tasto destro del mouse sull'icona Risorse del computer, su Proprietà, infine sulla scheda Nome computer:

Si supponga di memorizzare i due file contenuti in questo archivio compresso all'interno di un'unità di memorizzazione esterna (un hard disk rimovibile od una comunissima chiavetta USB).
Facendo doppio clic sul file backup.vbs (che può essere rinominato come meglio si crede, lasciando però inalterata l'estensione .VBS), lo script inizierà col creare, nell'unità dalla quale è stato lanciato, una cartella col nome corrispondente a quello del sistema in uso. Come passo successivo, il file VBS attingerà alle informazioni contenute nel file di configurazione config.ini ed avvierà la procedura di copia del contenuto delle cartelle in esso indicate.

A tal proposito, va evidenziato come lo script – per ciascun file – provveda a controllarne l'ultima data di modifica. Se un file presente nella directory sorgente risulta più aggiornato della versione ospitata nella cartella di backup, lo script VBS provvede ad effettuarne una copia. Viceversa, se le date di modifica sono identiche, non verrà effettuata la copia del file sull'unità di backup in modo da risparmiare tempo prezioso.
Il primo backup, infatti, a seconda delle dimensioni delle cartelle, può richiedere molto tempo per poter essere portato a completamento. Facendo successivamente doppio clic sul file VBS, questo provvederà a copiare solamente i file aggiornati riducendo nettamente le tempistiche necessarie per concludere l'operazione.

Dopo aver estratto i file backup.vbs e config.ini, ad esempio, in un'unità rimovibile, bisognerà cominciare con l'impostazione del file di configurazione. Il file config.ini, di default, si presenta così come segue:

; File di configurazione

; ISTRUZIONI:
; Per richiedere il backup del contenuto di cartelle specifiche, è necessario utilizzare la seguente struttura:
; 
; [NOMECOMPUTER]
; 1=C:\Documents and Settings\nomeutente\Documents\cartella
; 2=D:\Lavori\relazioni


Il file di configurazione è vuoto: come si vede contiene solo alcuni commenti (ogni riga inizia col carattere ;).

E' necessario, a questo, punto inserire il nome del computer correntemente in uso racchiundendolo tra due parentesi quadre. Al di sotto di tale indicazione (detta "sezione"; ved. questa pagina per maggiori informazioni sulla struttura dei file .INI), si devono indicare le cartelle oggetto di backup.
I percorsi debbono essere specificati nella forma seguente:
1=C:\Lavori
2=C:\Documents and Settings\Michele\Documents\Bozze
3=D:\Archivi\2011

Ciascun percorso, insomma, deve essere associato ad un numero progressivo (da 1 a n).

Esempio di un file di configurazione:
; File di configurazione

; ISTRUZIONI:
; Per richiedere il backup del contenuto di cartelle specifiche, è necessario utilizzare la seguente struttura:
; 
; [NOMECOMPUTER]
; 1=C:\Documents and Settings\nomeutente\Documents\cartella
; 2=D:\Lavori\relazioni

[HP-PC]
1=C:\Documents and Settings\Michele\Documents\Articoli IlSoftware.it
2=C:\Documents and Settings\Michele\Documents\HTML5
3=C:\Documents and Settings\Michele\Documents\Documenti personali

[VAIO-PC]
1=C:\Relazioni


In questo esempio, com'è facile verificare, ogniqualvolta lo script VBS dovesse essere avviato sul sistema denominato "HP-PC" verrà automaticamente copiato il contenuto delle tre cartelle indicate mentre nel caso del sistema "VAIO-PC", solamente la directory C:\Relazioni.

Facendo doppio clic sul file .VBS, inizierà l'operazione di copia vera e propria che sarà estesa a tutte le eventuali sottocartelle che dovessero essere presenti all'interno delle directory riportate dall'utente nel file .INI.

Al termine della procedura, lo script mostrerà un messaggio di cortesia che riporta, tra l'altro, il numero dei file copiati:

Nel caso in cui tutti i file presenti nella directory sorgente dovessero avere la medesima data di modifica degli elementi conservati nell'unità di backup, verrebbe mostrato il messaggio seguente (0 file copiati):

Riportiamo il contenuto del file VBS che abbiamo preparato:


' BACKUP AUTOMATICO FILE E CARTELLE - versione 0.1.2 - 16.05.2011
' File di esempio realizzato da Michele Nasi, IlSoftware.it - www.ilsoftware.it
' -----------------------------------------------------------------------------

'recupera il nome associato alla macchina in uso
Set WshNetwork = WScript.CreateObject("WScript.Network")
computername = WshNetwork.ComputerName

Set WshShell = WScript.CreateObject("WScript.Shell")

Const FOF_CREATEPROGRESSDLG = &H4&
Const FOF_NOCONFIRMATION = 16
Const FOF_NOCONFIRMDIRCREATE = 512

'recupera la cartella dalla quale è eseguito lo script VBS
ParentFolder = WshShell.CurrentDirectory

'crea una cartella col nome attribuito al sistema in uso
creadirectory ParentFolder,computername
if right(ParentFolder,1)<>"\" then ParentFolder=ParentFolder&"\"

Set fso = CreateObject("Scripting.FileSystemObject")
'imposta la cartella di destinazione (unitàcorrente:\nomecomputer\)
ComputernameFolder=ParentFolder&computername&"\"

c=1
f=0
do
	SourceFolder=ReadIni(ParentFolder&"config.ini",computername,c)
	if SourceFolder="" and c=1 then WScript.Echo "Il file di configurazione (config.ini) non è stato inizializzato per il sistema in uso ("& computername &")."&vbcrlf&"Aprirlo con un normale editor di testo e fare riferimento alle istruzioni."
	if SourceFolder=" " and c=1 then WScript.Echo "Per il sistema in uso non è stata indicata alcuna cartella sorgente."&vbcrlf&"Aprire il file config.ini con un normale editor di testo e fare riferimento alle istruzioni per modificarlo."

	if trim(SourceFolder)<>"" then
		if fso.FolderExists(SourceFolder) then
			creadirectory ComputernameFolder,lastfolder(SourceFolder)
			DestinationFolder=ComputernameFolder&lastfolder(SourceFolder)
			copia SourceFolder,DestinationFolder
		else
			WScript.Echo "La cartella "& SourceFolder &" non esiste."&vbcrlf&"Impossibile copiare i dati nell'unità di destinazione."
		end if
	end if
	c=c+1
loop until SourceFolder="" or SourceFolder=" "

function copia(sorgente,destinazione)
	Set fileCol = fso.GetFolder(sorgente).Files
	Set dirCol = fso.GetFolder(sorgente).Subfolders
	
	if right(destinazione,1)<>"\" then destinazione=destinazione&"\"
	
	For Each objSubfolder in dirCol
	   sottodirectory=objSubfolder.Name
	   creadirectory destinazione,sottodirectory
	   copia sorgente&"\"&sottodirectory,destinazione&sottodirectory
	Next
	
	' WScript.Echo sorgente &" -- "& destinazione
	
	For Each objFile in fileCol
	    If not fso.FileExists(destinazione & objFile.Name) Then
		' Copia il file se non esiste nella cartella di destinazione
		objFile.Copy destinazione
		f=f+1
	    Else
		If objFile.DateLastModified > fso.GetFile(destinazione & objFile.Name).DateLastModified Then
			'Se il file sorgente è più recente di quello di destinazione procede con la copia
			objFile.Copy destinazione, True
			f=f+1
		End If
	    End If
	Next 
	Set fileCol=Nothing
	Set dirCol=Nothing
end function

function lastfolder(percorso)
	s=array()
	if instr(percorso,"\") > 0 then
		s=split(percorso,"\")
		lastfolder = s(ubound(s))
	end if
end function

function creadirectory (nomedirectory,dirdacreare)
	Set objShell = CreateObject("Shell.Application")
	Set objFolder = objShell.NameSpace(nomedirectory) 
	objFolder.NewFolder dirdacreare
	
	Set objFolder=Nothing
	Set objShell=Nothing
end function

Function ReadIni(myFilePath, mySection, myKey)
    ' This function returns a value read from an INI file
    '
    ' Arguments:
    ' myFilePath  [string]  the (path and) file name of the INI file
    ' mySection   [string]  the section in the INI file to be searched
    ' myKey       [string]  the key whose value is to be returned
    '
    ' Returns:
    ' the [string] value for the specified key in the specified section
    '
    ' CAVEAT:     Will return a space if key exists but value is blank
    '
    ' Written by Keith Lacelle
    ' Modified by Denis St-Pierre and Rob van der Woude
    ' Riga 128 modificata da Michele Nasi

    Const ForReading   = 1
    Const ForWriting   = 2
    Const ForAppending = 8

    Dim intEqualPos
    Dim objFSO, objIniFile
    Dim strFilePath, strKey, strLeftString, strLine, strSection

    Set objFSO = CreateObject("Scripting.FileSystemObject")

    ReadIni     = ""
    strFilePath = Trim( myFilePath )
    strSection  = Trim( mySection )
    strKey      = Trim( myKey )

    If objFSO.FileExists( strFilePath ) Then
        Set objIniFile = objFSO.OpenTextFile( strFilePath, ForReading, False )
        Do While objIniFile.AtEndOfStream = False
            strLine = Trim( objIniFile.ReadLine )

            ' Check if section is found in the current line
            If LCase( strLine ) = "[" & LCase( strSection ) & "]" Then
            	if not objIniFile.AtEndOfStream then strLine = Trim(objIniFile.ReadLine)

                ' Parse lines until the next section is reached
                Do While Left( strLine, 1 ) <> "["
                    ' Find position of equal sign in the line
                    intEqualPos = InStr( 1, strLine, "=", 1 )
                    If intEqualPos > 0 Then
                        strLeftString = Trim( Left( strLine, intEqualPos - 1 ) )
                        ' Check if item is found in the current line
                        If LCase( strLeftString ) = LCase( strKey ) Then
                            ReadIni = Trim( Mid( strLine, intEqualPos + 1 ) )
                            ' In case the item exists but value is blank
                            If ReadIni = "" Then
                                ReadIni = " "
                            End If
                            ' Abort loop when item is found
                            Exit Do
                        End If
                    End If

                    ' Abort if the end of the INI file is reached
                    If objIniFile.AtEndOfStream Then Exit Do

                    ' Continue with next line
                    strLine = Trim( objIniFile.ReadLine )
                Loop
            Exit Do
            End If
        Loop
        objIniFile.Close
    Else
        WScript.Echo strFilePath & " non esiste. Crearlo e riavviare lo script."
        Wscript.Quit 1
    End If
End Function

Set fso=Nothing
Set WshShell=Nothing
Set WshNetwork=Nothing
WScript.Echo "Operazione completata."&vbcrlf&f&" file copiati."
WScript.Quit




Per le operazioni di lettura del file .INI abbiamo "riciclato" il codice realizzato da K. Lacelle e modificato da Denis St-Pierre, Johan Pol e Rob van der Woude (pubblicato a questo indirizzo). Per evitare la comparsa di un errore nel caso di una scorretta configurazione del file .INI, abbiamo modificato la riga 128.

La parte principale dello script è quella compresa tra le righe 26 e 43 (ciclo do ... loop). Per ciascuna directory oggetto di backup (letta dal file .INI attraverso l'istruzione alla riga 29), viene dapprima creata una cartella – ove necessario – nel percorso di destinazione (riga 35) quindi invocata la funzione copia. Si tratta di un algoritmo ricorsivo (righe 45-74) che, per ciascuna eventuale sottocartella, provvede a richiamare se stesso effettuando la copia dei file, se necessario. Utilizzando il ciclo for ... next (righe 59-71), infatti, si provvede a copiare tutti quei file che non esistono ancora nel percorso di destinazione mentre si evita la copia di quegli elementi che non appaiono aggiornati (stessa data di modifica sia nella directory sorgente che in quella di destinazione).

Qualora aveste dei dubbi sul funzionamento dello script, vi invitiamo a richiedere spiegazioni inviando un commento in calce a questo articolo.


  1. Avatar
    Michele Nasi
    18/05/2011 07:59:44
    Il file da modificare per le proprie esigenze è il CONFIG.INI. Le indicazioni per procedere sono riportate nella prima parte dell'articolo.
  2. Avatar
    activa
    18/05/2011 00:28:53
    E' un po confuso quali siano le parti da modificare per la propia esigenza, se fossero in grassetto, o di un altro colore si capirebbe meglio. Grazie per l'articolo molto utile.
  3. Avatar
    sandrozi
    17/05/2011 14:37:13
    Ciao a tutti, ho provato subito questo script perchè avevo un'esigenza urgente. Ha funzionato benissimo. :D
Automatizzare il backup del contenuto di qualunque cartella con uno script VBS - IlSoftware.it