none
ayuda para copiar folders y archivos manteniendo la misma estructura RRS feed

  • Pregunta

  • que tal, aclarando  primero que no tengo conocimientos de VBscript asi que necesito de su ayuda, he creado un script (en realidad solo lo he ensamblado usado la logica), bueno lo que espero de este script es que me cree un folder apartir del nombre de la maquina(ya lo hace), que me compare si es que el archivo fue modificado en un periodo 'X' y encaso de ser mayor el periodo copiarlo a otra carpeta (la que se creo con el nombre de la maquina), ya tambien lo hace pero el detalle y es en el que necesito de su ayuda, cuando hace la comparacion al parecer no la hace en realidad y comienza a copiar todos los archivos, y mas aparte cuando hace las comparaciones dentro de los subfolders me crea el subfolder en el folder raiz en lugar de crearlo en el folder qeu le corresponde ejemplo

    c:\ folder1\ folder2\ folder3 

    c:\folder1\archivo1.txt

    c:\folder1\folder2\archivo2.txt

    se supondria que me crearia la misma estructura en X:\computername\

    pero me hace lo siguiente

    X:\computername\ folder1\archivo1.txt

    X:\computername\ folder2\archivo2.txt

    X:\computername\ folder3

    c:\ folder1\ folder2\ folder3 

    c:\folder1\archivo1.txt

    c:\folder1\folder2\archivo2.txt

     si alguien me puede decir en uqe esta mal el codigo se los agradecere bastante.

     

    'Get name of pc and create a folder
    
    Set wshShell = WScript.CreateObject( "WScript.Shell" )
    	strComputerName = wshShell.ExpandEnvironmentStrings( "%COMPUTERNAME%" )
    	WScript.Echo "Computer Name: " & strComputerName
    dim filesys, folder
    folPath = "I:\" & strComputerName 
    set filesys=CreateObject("Scripting.FileSystemObject") 
    	If Not filesys.FolderExists(folPath) Then 
    		Set folder = filesys.CreateFolder(folPath) 
    	End If
    'create logfile
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Const ForAppending = 2
    Dim objFSO:Set objFSO = CreateObject("Scripting.FileSystemObject")
    	LogFile = "c:\exportme.log"
    Dim objLogFile:Set objLogFile = objFSO.CreateTextFile(logfile, 2, True)
    	objStartFolder = "C:\xampp"
    	Set objFolder = objFSO.GetFolder(objStartFolder)
    		objLogFile.Write objFolder.Path
    		objLogFile.Writeline
    Set colFiles = objFolder.Files
    	For Each objFile in colFiles
        	    objLogFile.Write objFolder.Path & "\" & objFile.Name
        	    objLogFile.Writeline 
       	Next
    'browse in folder and subfolders to compare
    ShowSubfolders objFSO.GetFolder(objStartFolder)
    Sub ShowSubFolders(Folder)
    
    For Each Subfolder in Folder.SubFolders
            objLogFile.Write Subfolder.Path
    	objLogFile.Writeline
            Set objFolder = objFSO.GetFolder(Subfolder.Path)
    	Set colFiles = objFolder.Files
            For Each objFile in colFiles
    		If objFolder.DateLastModified < (Now() -30) Then
    		
    		objfolder.copy folPath & "\" 
    		objLogFile.Write Subfolder.Path & "\" & objFile.Name  
               	objLogFile.Writeline
    		
    end if
    	
       next
    	
            ShowSubFolders Subfolder
    	
        Next
    
    End Sub
    objLogFile.Close
    
    
    WScript.Echo "Done!"

    Gracias de antemano....


    Pablo Sanchez HD
    martes, 6 de septiembre de 2011 4:43

Respuestas

  • Vamos a ver, para lo que pides, podría ser algo así:

     

    @ECHO OFF
    REM Primero averiguamos si existe la carpeta de destino
    REM En caso contrario la creamos. Para facilitar la tarea
    REM creamos la variable DESTINO
    SET DESTINO=X:\%COMPUTERNAME%
    REM Para saber si la carpeta existe, intentamos cambiar el
    REM inductor a ella; si se produce error es que no existe
    REM y por tanto tenemos que crearla
    CD %DESTINO%
    IF ERRORLEVEL 1 MKDIR %DESTINO%
    
    REM Una vez creada la carpeta realizamos la copia
    REM usaremos los modificadores siguientes:
    REM    + /E - provoca que se copie toda la estructura de directorios
    REM             incluidos los vacíos.
    REM    + /COPYALL - provoca que se copie toda la información de los
    REM             archivos (datos, atributos, marcas de tiempo,
    REM             seguridad, propietario y auditorías)
    REM    + /MINAGE:x - esto hace que sólo se copien los ficheros que
    REM             que no hayan sido modificados en los últimos x días
    REM             (en este caso establecemos 30 días)
    REM    + /R:x - número de veces que se reintentará copiar un fichero
    REM             en el caso de que falle la copia. Se reintentará copiar
    REM             pasados 30 segundos; en caso de querer varia este
    REM             este intervalo de espera se debe añadir el parámetro
    REM             /W:x, siendo x el número de segundos a esperar
    REM    + /LOG:fichero - ruta y nombre del fichero de log en el que
    REM            se guardará la información del proceso
    REM    + /TEE - además de guardar el progreso en el fichero de log
    REM            lo mostrará por pantalla             
    ROBOCOPY C:\xampp %DESTINO% /E /COPYALL /MINAGE:30 /R:2 /LOG:c:\exportme.log /TEE


     


    Un saludo

    Fernando Reyes [MS MVP]
    MCSA 2000/2003
    MCSE 2000/2003
    MCITP EnterpriseAdministrator
    Web: http://freyes.svetlian.com
    Blog: http://urpiano.wordpress.com
    RSS: http://urpiano.wordpress.com/feed/
    freyes.champú@champú.mvps.org
    (Aclárate la cabeza si quieres escribirme)
    • Marcado como respuesta PabloSanG jueves, 8 de septiembre de 2011 7:17
    miércoles, 7 de septiembre de 2011 9:27
    Moderador
  • Para que no de error al crear la carpeta si ya existe, deberías primero comprobar la existencia:

            If des1 <> "\\servidor4\Facturas\" & aiio & "" Then
                compara = True
                If Dir("\\servidor4\Facturas\" & aiio & "",vbDirectory) = "" Then _
                    MkDir("\\servidor4\Facturas\" & aiio & "")
            End If
    
            If Dir("" & des1 & "/" & mes & "",vbDirectory) = "" Then _
                MkDir("" & des1 & "/" & mes & "")

    No estoy seguro, pero creo que la comparacion de nombres que realizas deberías cuidar que no se viera afectada por el caso:

    If nombre.ToUpper() <> nombre2.ToUpper() Then

    No obstante, por lo que veo se trata de .NET; deberías preguntar en los foros de MSDN, en concreto creo que en el de VB .NET:

    http://social.msdn.microsoft.com/Forums/es-ES/vbes/threads

     


    Un saludo

    Fernando Reyes [MS MVP]
    MCSA 2000/2003
    MCSE 2000/2003
    MCITP EnterpriseAdministrator
    Web: http://freyes.svetlian.com
    Blog: http://urpiano.wordpress.com
    RSS: http://urpiano.wordpress.com/feed/
    freyes.champú@champú.mvps.org
    (Aclárate la cabeza si quieres escribirme)


    jueves, 27 de octubre de 2011 6:30
    Moderador

Todas las respuestas

  • Creo que te estás complicando la vida... ¿Porqué no miras si te vale Robocopy, que permite realizar copias de ficheros, con estructura e incluso actualizar en la copia los que han cambiado en el origen?

    Un saludo

    Fernando Reyes [MS MVP]
    MCSA 2000/2003
    MCSE 2000/2003
    MCITP EnterpriseAdministrator
    Web: http://freyes.svetlian.com
    Blog: http://urpiano.wordpress.com
    RSS: http://urpiano.wordpress.com/feed/
    freyes.champú@champú.mvps.org
    (Aclárate la cabeza si quieres escribirme)
    martes, 6 de septiembre de 2011 9:07
    Moderador
  • claro que robocopy es una buena opcion pero no le comprendo del todo a la estructura, con vbscript alcanzo a comprender lo que hace si tuvieras algun ejemplo de mi caso estaria perfecto para aplicarlo y ver si trabaja a como requiero....

     

    Gracias. 


    Pablo Sanchez HD
    martes, 6 de septiembre de 2011 23:20
  • Vamos a ver, para lo que pides, podría ser algo así:

     

    @ECHO OFF
    REM Primero averiguamos si existe la carpeta de destino
    REM En caso contrario la creamos. Para facilitar la tarea
    REM creamos la variable DESTINO
    SET DESTINO=X:\%COMPUTERNAME%
    REM Para saber si la carpeta existe, intentamos cambiar el
    REM inductor a ella; si se produce error es que no existe
    REM y por tanto tenemos que crearla
    CD %DESTINO%
    IF ERRORLEVEL 1 MKDIR %DESTINO%
    
    REM Una vez creada la carpeta realizamos la copia
    REM usaremos los modificadores siguientes:
    REM    + /E - provoca que se copie toda la estructura de directorios
    REM             incluidos los vacíos.
    REM    + /COPYALL - provoca que se copie toda la información de los
    REM             archivos (datos, atributos, marcas de tiempo,
    REM             seguridad, propietario y auditorías)
    REM    + /MINAGE:x - esto hace que sólo se copien los ficheros que
    REM             que no hayan sido modificados en los últimos x días
    REM             (en este caso establecemos 30 días)
    REM    + /R:x - número de veces que se reintentará copiar un fichero
    REM             en el caso de que falle la copia. Se reintentará copiar
    REM             pasados 30 segundos; en caso de querer varia este
    REM             este intervalo de espera se debe añadir el parámetro
    REM             /W:x, siendo x el número de segundos a esperar
    REM    + /LOG:fichero - ruta y nombre del fichero de log en el que
    REM            se guardará la información del proceso
    REM    + /TEE - además de guardar el progreso en el fichero de log
    REM            lo mostrará por pantalla             
    ROBOCOPY C:\xampp %DESTINO% /E /COPYALL /MINAGE:30 /R:2 /LOG:c:\exportme.log /TEE


     


    Un saludo

    Fernando Reyes [MS MVP]
    MCSA 2000/2003
    MCSE 2000/2003
    MCITP EnterpriseAdministrator
    Web: http://freyes.svetlian.com
    Blog: http://urpiano.wordpress.com
    RSS: http://urpiano.wordpress.com/feed/
    freyes.champú@champú.mvps.org
    (Aclárate la cabeza si quieres escribirme)
    • Marcado como respuesta PabloSanG jueves, 8 de septiembre de 2011 7:17
    miércoles, 7 de septiembre de 2011 9:27
    Moderador
  • muchas gracias Fernando, en este momento estoy corriendo algunas pruebas con el codigo que me otorgaste antes de poderlo aplicar a mis servidores.

    solo existe un ligero detalle, en las pruebas si le otorgo el destino dentro de una serie de subfolders, veo que me comienza a copiar desde ese folder pero no me crea la ruta absoluta, es decir cuando selecciono subfolder dentro de "c:\folder\subfolder\subsubfolder\archivo.txt" solo crea "x:\destino\subsubfolder\archivo.txt", lo que estoy buscando es tener la ruta absoluta desde raiz.

    Te agradesco el apoyo, ya que me he dado cuenta que tienes razon me estaba complicando la vida.


    Pablo Sanchez HD
    jueves, 8 de septiembre de 2011 7:17
  • ¿Puedes poner el comando robocopy que lanzas en concreto?

    Un saludo

    Fernando Reyes [MS MVP]
    MCSA 2000/2003
    MCSE 2000/2003
    MCITP EnterpriseAdministrator
    Web: http://freyes.svetlian.com
    Blog: http://urpiano.wordpress.com
    RSS: http://urpiano.wordpress.com/feed/
    freyes.champú@champú.mvps.org
    (Aclárate la cabeza si quieres escribirme)
    jueves, 8 de septiembre de 2011 7:44
    Moderador
  • es el mismo que me otrogaste pero he estado haciendo pruebas,  y como te comento me hace falta la opcion de copiar la ruta completa. Te agradesco tu atencion y que tengas excelente dia...

    ROBOCOPY C:\xampp %DESTINO% /E /COPYALL /MINAGE:30 /R:2 /LOG:c:\exportme.log

     

     


    Pablo Sanchez HD
    jueves, 8 de septiembre de 2011 8:05
  • Aquí creo quie hay algo que no entiendo...

    Si yo ejecuto el script poniendo:

     

    ROBOCOPY p:\Prueba\1 %DESTINO% /E /COPYALL /MINAGE:30 /R:2 /LOG:c:\exportme.log /TEE

     

    Si destino es x:\nombreequipo, me crea un árbol exactamente igual al que tiene su inicio en  p:\prueba\1. Esto quiere decir que si en p:\prueba\1 existe la carpeta p:\prueba\1\2 y dentro de ella la p:\prueba\1\2\3, robocopy crea en x:\nombreequipo las carpetas x:\nombreequipo\2 y x:\nombreequipo\2\3. Si lo que quisiera es que se crease también la carpeta x:\nombreequipo\1, tendría que lanzar robocopy con el origen p:\Prueba, no con p:Prueba\1. Claro, me dirás que en c:\Prueba hay otras carpetas que no quieres copiar; por tanto lo mejor sería agregar ese nombre de carpeta al destino, es decir que la línea de establecimiento de la variable DESTINO se cambiara a:

     

    SET DESTINO=X:\%COMPUTERNAME%\xampp

     

     


    Un saludo

    Fernando Reyes [MS MVP]
    MCSA 2000/2003
    MCSE 2000/2003
    MCITP EnterpriseAdministrator
    Web: http://freyes.svetlian.com
    Blog: http://urpiano.wordpress.com
    RSS: http://urpiano.wordpress.com/feed/
    freyes.champú@champú.mvps.org
    (Aclárate la cabeza si quieres escribirme)
    jueves, 8 de septiembre de 2011 9:53
    Moderador
  • Correcto tendria que agregar en el destino la ruta especifica si quiero copiar un subfolder pero con la ruta completa, en este caso asi funciona perfecto tambien, agradesco tu ayuda. Sigo corriendo pruebas y dentro de poco podremos liberar espacio en nuestros servidores, nuevamente gracias. Saludos desde Tijuana, Mexico.


    Pablo Sanchez HD
    sábado, 10 de septiembre de 2011 1:51
  • Hola Buen dia. gracias a la ayuda que le brindo a Pablo me atrevo a solicitarle tambien ayuda respecto a algo parecido. Vera necesito crear una aplicacion de consola que copie archivos de cualquier direccion en la que se encuentre hasta una carpeta en un servidor. ese no es el problema, mi problema viene cuando mi aplicacion ya que se conecta con su usuario propio al servidor, solo permita copiar archivos, pero que no puedan ser reemplazados ejecutando de nuevo el programa, ya que seran facturas las que se van a almacenar y por serguridad debe ser asi. solo permita copiar archivos, pero que no los reemplace. lo que llevo del codigo es lo siguiente:


        Public Sub main()

            Dim aiio As String
            Dim mes As String

            Console.WriteLine("")
            Console.WriteLine("Dime el año")
            aiio = Console.ReadLine()
            Console.WriteLine("Dame el mes")
            mes = Console.ReadLine()

            Shell("net use I: \\servidor4\Facturas /User:dominio.com.mx\sistema 9874")


            Dim des1 As String = "\\servidor4\Facturas\" & aiio & ""
            Dim compara As Boolean = False

            If des1 <> "\\servidor4\Facturas\" & aiio & "" Then
                compara = True
                MkDir("\\servidor4\Facturas\" & aiio & "")
            End If

            MkDir("" & des1 & "/" & mes & "")
            Dim des2 As String = "\\servidor4\Facturas\" & aiio & "\" & mes & ""
            Dim local As String = "c:\"

            Dim Archivo As System.Collections.ObjectModel.ReadOnlyCollection(Of String)
            Archivo = My.Computer.FileSystem.GetFiles("" & local & FileIO.SearchOption.SearchTopLevelOnly)

            For Each nombre As String In Archivo

                Dim Archivo2 As System.Collections.ObjectModel.ReadOnlyCollection(Of String)
                Archivo2 = My.Computer.FileSystem.GetFiles("" & des2 & True, FileIO.SearchOption.SearchTopLevelOnly)

                For Each nombre2 As String In Archivo2
                    If nombre <> nombre2 Then
                        Shell("C:\Windows\system32\xcopy.exe "" \\servidor4\Facturas\" & aiio & "\" & mes & "/I /Y /Q /E /H")
                        Shell("net use I: /d")
                    End If
                Next
            Next
        End Sub
    End Module

     

     

    y lo unico que hace es generar las carpetas jajaja. Ademas de que si ya esta creada la carpeta el mes, me sale error, como puedo corregirlo??? me podria ayudar?? por favor esque sobre esto de consola no se mucho.

    miércoles, 26 de octubre de 2011 16:05
  • Para que no de error al crear la carpeta si ya existe, deberías primero comprobar la existencia:

            If des1 <> "\\servidor4\Facturas\" & aiio & "" Then
                compara = True
                If Dir("\\servidor4\Facturas\" & aiio & "",vbDirectory) = "" Then _
                    MkDir("\\servidor4\Facturas\" & aiio & "")
            End If
    
            If Dir("" & des1 & "/" & mes & "",vbDirectory) = "" Then _
                MkDir("" & des1 & "/" & mes & "")

    No estoy seguro, pero creo que la comparacion de nombres que realizas deberías cuidar que no se viera afectada por el caso:

    If nombre.ToUpper() <> nombre2.ToUpper() Then

    No obstante, por lo que veo se trata de .NET; deberías preguntar en los foros de MSDN, en concreto creo que en el de VB .NET:

    http://social.msdn.microsoft.com/Forums/es-ES/vbes/threads

     


    Un saludo

    Fernando Reyes [MS MVP]
    MCSA 2000/2003
    MCSE 2000/2003
    MCITP EnterpriseAdministrator
    Web: http://freyes.svetlian.com
    Blog: http://urpiano.wordpress.com
    RSS: http://urpiano.wordpress.com/feed/
    freyes.champú@champú.mvps.org
    (Aclárate la cabeza si quieres escribirme)


    jueves, 27 de octubre de 2011 6:30
    Moderador
  • Cierto tiene mucha razon. Muchas gracias por su ayuda. Que este bien. Un saludo

    jueves, 27 de octubre de 2011 18:28