El Blog de Gualtrysoft

Windows 2000/2003/2008, Active Directory, VBScript, Hyper-V, PowerShell y todo aquello interesante a la hora de usar, configurar y administrar Windows Server. También tenemos longanizas…

Script Para Borrar Ficheros Viejos

Posted by urpiano en viernes 9 \09\+01:00 febrero \09\+01:00 2007

Este script permite borrar los ficheros contenidos en uina carpeta cuya fecha de última modificación sea anterior a la fecha que se le pasa como parámetro.

'Este script recibe como parámetros una ruta de carpeta y una fecha en
'formato DD/MM/YYYY y borra todos aquellos ficheros ubicados en la ruta
'que indica la carpeta que tengan como fecha de última modificación
'una igual o anterior a la recibida como parámetro. Si se añade el
'modificador /R el borrado se hará en todo el árbol cuya raíz es el 
'parámetro de ruta recibido. Ejemplo: 

'cscript borrar-ficheros-hasta-fecha.vbs /R c:Carpeta 23/11/2003

'© Noviembre de 2006 - Fernando Reyes

'Febrero de 2007:
'Se añade el parámetro /R por el cual se realizará un borrado de forma
'recursiva, esto es, de la carpeta recibida y de todo el subárbol que
'contiene

Option Explicit

Dim str_Fecha
Dim bol_Recursivo
Dim str_Ruta
Dim dth_Fecha

WScript.Echo "1.- " & WScript.Arguments(0)

WScript.Echo "2.- " & WScript.Arguments(1)

'Comprobamos que hemos recibido el número correcto de parámetros
'recibidos
If WScript.Arguments.Unnamed.Count <> 2 Then


    WScript.Echo "Error 1: Número de parámetros incorrecto. " & _
          "Se deben pasar 2:" & _
          vbCrLf & vbCrLf & _
          " 1.- Ruta de la carpeta donde borrar los ficheros." & _
          vbCrLf & _
           " 2.- Fecha de última modificación a partir de la cual" & _
           vbCrLf & _
           " se borrarán los ficheros anteriores y de la misma fecha " & _
           "(DD/MM/YYYY)." & vbCrLf & vbCrLf & _
           "Se puede agregar el modificador /R para que haga " & _
           "el borrado de forma recursiva" & vbCrLf & _
           vbCrLf & _
           "Ejemplo:" & vbCrLf & vbCrLf & _
           "cscript borrar-ficheros-hasta-fecha.vbs /R " & _
           "c:Carpeta 23/11/2003"
    WScript.Quit 1

End If

If WScript.Arguments.Named.Exists("R") Then bol_Recursivo = True

str_Ruta = WScript.Arguments.Unnamed(0)
dth_Fecha = WScript.Arguments.Unnamed(1)

Call s_BorrarFicheros(str_Ruta, dth_Fecha, bol_Recursivo)

Sub s_BorrarFicheros(str_Ruta, dth_Fecha, bol_Recursivo)

    Dim obj_FSO
    Dim obj_Carpeta
    Dim obj_Fichero

    'Creamos el objeto FileSystemObject
    Set obj_FSO = CreateObject("Scripting.FileSystemObject")
    
    'Comprobamos que la ruta recibida sea válida
    If not obj_FSO.FolderExists(str_Ruta) Then
    
        WScript.Echo "Error 2: La carpeta " & str_Ruta & _
                           " recibida como parámetro no existe."
        Set obj_FSO = Nothing
        WScript.Quit 2
    
    End If
    
    'Comprobamos que la fecha recibida sea válida
    If not IsDate(dth_Fecha) Then
    
        WScript.Echo "Error 3: La fecha " & dth_Fecha & _
                     " recibida como parámetro no es una fecha válida."
        Set obj_FSO = Nothing
        WScript.Quit 3
    
    End If
    
    'Creamos el objeto carpeta
    Set obj_Carpeta = obj_FSO.GetFolder(str_Ruta)
    
    'Recorremos los ficheros contenidos en la carpeta
    For Each obj_Fichero In obj_Carpeta.Files
    
        'Comprobamos que la fecha de última modificación del fichero
        'sea anterior o igual a la recibida como parámetro
    
        If DateValue(obj_Fichero.DateLastModified) <= _
                                        DateValue(dth_Fecha) Then
    
            'En caso afirmativo, mostramos el nombre y fecha del fichero
            'y lo borramos
            WScript.Echo "Borrando " & obj_Fichero.Name & _
            ": Modificado el " & _
            obj_Fichero.DateLastModified
            'Borramos el fichero incluso en el caso de ser de sistema, si 
            'quisiéramos que  no se borren los de sistema, tan sólo
            'debemos eliminar el True o sustituirlo por False
            obj_Fichero.Delete True
    
        End If
    
    Next
    
    'Si queremos que se recorra todo el subárbol de carpetas...
    If bol_Recursivo Then

        'Definimos un objeto para las subcarpetas
        Dim obj_Subcarpeta
        
        'Recorremos las subcarpetas en este bucle
        For Each obj_Subcarpeta In obj_Carpeta.Subfolders
        
            'Llamada recursiva para borrar los ficheros de la
            'subcarpeta
            Call s_BorrarFicheros(obj_Subcarpeta.Path,dth_Fecha, _
                                         bol_Recursivo)
        
        Next
        
        Set obj_Subcarpeta = Nothing   
    
    End If
    
    'Nos limpiamos el culito antes de terminar :-))
    Set obj_Fichero = Nothing
    Set obj_Carpeta = Nothing
    Set obj_FSO = Nothing

End Sub

31 respuestas to “Script Para Borrar Ficheros Viejos”

  1. thefame said

    Hola.

    Antes de nada felicitarte por el script.

    La verdad es que le encuentro un pequeño problema. Como he de hacerlo para que sea recursivo la busqueda de ficheros en la carpeta que le dices??

    Muchas gracias.

    Atentamente,
    thefame

  2. thefame said

    Hola de nuevo.

    He estado indagando en el tema y he conseguido hacer que sea recursivo solo en un solo nivel, aunque creo que para hacerlo recursivo mas de 1 vez tendremos que repetir el codigo que pongo tantas veces como queramos podras llegar a hacerlo recursivo.


    Dim sf
    Dim f1

    Set sf = obj_Carpeta.SubFolders

    For Each f1 in sf

    For Each obj_Fichero In f1.Files

    'Comprobamos que la fecha de última modificación del fichero sea anterior
    'o igual a la recibida como parámetro

    If DateValue(obj_Fichero.DateLastModified)

  3. thefame said

    Codigo completo:

    Dim sf
    Dim f1

    Set sf = obj_Carpeta.SubFolders

    For Each f1 in sf

    For Each obj_Fichero In f1.Files

    ‘Comprobamos que la fecha de última modificación del fichero sea anterior
    ‘o igual a la recibida como parámetro

    If DateValue(obj_Fichero.DateLastModified)

  4. thefame said

    Hola de nuevo.

    No se que pasa que no me deja poner el codigo entero.
    Pido al administrador que borre el post anterior.

    Gracias

  5. urpiano said

    Acabo de subir esta nueva versión del script que hace lo que quieres. Cuando desees que el borrado sea recursivo, debes añadir el modificador «/R»

  6. Silverio said

    Hola buenas,

    Gracias por la ayuda que supone a la gente que no dominamos los script.

    Estoy intentando que me funcione pero me da varios errores. Al borrar de manera recursiva, con el /R, supone un tercer argumento, por lo que argument(0) no sería la ruta si no el /R. Luego a la hora de buscar en las subcarpetas le pasas la ruta, pero me parece que se produce un bucle en: Set obj_Carpeta = obj_FSO.GetFolder(WScript.Arguments(0)), porque vuelve a coger el valor de la ruta pasada desde la línea de comandos.

    Si puedes echarme una mano, gracias de antemano y un saludo.

  7. urpiano said

    ¡Esto me pasa por sobrado y por no haber probado el script antes de publicarlo! :-) Hay un gazapo en la línea:

    Set obj_Carpeta = obj_FSO.GetFolder(WScript.Arguments(0))

    Debería ser:

    Set obj_Carpeta = obj_FSO.GetFolder(str_Ruta)

    Este gazapo provoca el bucle que dices, pues hace que siempre se procese la misma carpeta.

    Hay otro gazapo en la línea:

    If DateValue(obj_Fichero.DateLastModified) <= _
                     DateValue(WScript.Arguments(1)) Then

    Debería ser:

    If DateValue(obj_Fichero.DateLastModified) <= _
                     DateValue(dth_Fecha) Then

    Este gazapo no provoca ningún error si se sitúa el modificador /R como último parámetro; en el momento que que sea el primero o el segundo el error se produce.

    Estas líneas eran correctas cuando el script no era recursivo, le añadí la recursividad y se me escaparon. Como no estaba el modificador /R, se podía uno referir a los parámetros como WScript.Arguments(0) o WScript.Arguments(1); una vez añadido el modificador /R, es necesario hacerlo como WScript.Arguments.Unnamed(0) y WScript.Arguments.Unnamed(1), de esa manera no se falsea si pones /R delante, o en medio, de los otros parámetros.

    Gracias por avisarme, lo he retocado, espero que te funcione ahora sin problemas.

  8. kike said

    Está genial.

    Tengo una duda, a ver si me podeis ayudar. Utilizo un metodo similar para visualizar las imágenes de una carpeta del servidor.

    dim fs2,fo2,x2
    set fs2=Server.CreateObject(«Scripting.FileSystemObject»)
    Path = session(«eldirectoriofisico»)
    set fo2=fs2.GetFolder(path)
    for each x2 in fo2.files
    ‘visualizo la imagen de x2
    next

    Todo perfecto pero el tema es que lo visualiza ordenado por nombre del fichero y a mi me interesa que lo visualice ordenado por fecha de modificación. Sabeis como puedo hacerlo?

    Gracias

  9. urpiano said

    Para eso necesitas cargar los nombres de los ficheros y su tamaño en un array de dos dimensiones, ordenar el array y luego recorrelo. Mira si te ayuda este enlace:

    ASPFAQS (118): FileSystemObject – How to Sort Files

  10. enec said

    Buenas,

    He probado el script de forma no recursiva y funciona correctamente, el problema viene cuando intento hacerlo recursivo con /R, por mucho que cambie el modificador de posicion tengo siempre el mismo problema, aqui lo muestro:


    C:\prueba>cscript scritp.vbs yo 06/06/2007 /R
    Microsoft (R) Windows Script Host versión 5.6
    Copyright (C) Microsoft Corporation 1996-2001. Reservados todos los derechos.

    1.- yo
    2.- 06/06/2007
    Error 1: Número de parámetros incorrecto. Se deben pasar 2:

    1.- Ruta de la carpeta donde borrar los ficheros.
    2.- Fecha de última modificación a partir de la cual
    se borrarán los ficheros anteriores y de la misma fecha (DD/MM/YYYY).

    Se puede agregar el modificador /R para que haga el borrado de forma recursiva

    Ejemplo:

    cscript borrar-ficheros-hasta-fecha.vbs /R c:\Carpeta 23/11/2003

    C:\prueba>

    ¿que hago mal? ¿alguna solucion?

  11. urpiano said

    No es culpa tuya, si no mía por no haberlo testeado. El problema estaba en la línea:

    If WScript.Arguments.Count <> 2 Then

    Que debería haber sido:

    If WScript.Arguments.Unnamed.Count <> 2 Then

    Lo he modificado, prueba ahora

  12. enec said

    Gracias, :-)

    ya funciona correctamente, solo que hay que cambiar

    Call s_BorrarFicheros(obj_Subcarpeta.Path,dthFecha, _
    bol_Recursivo)

    por
    Call s_BorrarFicheros(obj_Subcarpeta.Path,dth_Fecha, _
    bol_Recursivo)

  13. urpiano said

    Lo dicho, que me pasa por no testearlo. El script lo desarrollé sin recursividad, por petición de un oyente le hice la recursividad con prisas, no tenía demasiado tiempo para andar testeando en condiciones, lo que ha provocado este tipo de errores. Cada vez que le he metido mano desde entonces me ha pillado a contrapié y lo he depurado sin probar. Muchas gracias por buscarme ese gazapo. Paso a corregirlo.

  14. Martin said

    Muy buen trabajo, ante todo. Lo que te queria consultar, ante la imposibilidad de hacerlo yo dado que no programo en este lenguaje, es si existe posibilidad de que haga exactamente lo que hace, pero solo en cierto tipo de archivos. Es decir, poder pasarle que borre solo archivos de audio .mp3 o de video .wmv, por decir algo.

    Gracias desde ya por tan buen trabajo, nos vemos.

  15. Martin said

    Hola a todos,

    Pude solucionar el tema de elegir un tipo de archivos especifico, si bien seguramente no es de la mejor manera. Simplemente se modifico la linea:

    If DateValue(obj_Fichero.DateLastModified) <= _
    DateValue(dth_Fecha) Then

    Por esta otra:

    If DateValue(obj_Fichero.DateLastModified) <= _
    DateValue(dth_Fecha) and (obj_FSO.GetExtensionName(obj_Fichero.Path)=»wmv» or obj_FSO.GetExtensionName(obj_Fichero.Path)=»WMV») Then

    Saludos!

  16. urpiano said

    Martín:

    Es correcta tu solución, pero sería más simple si usases UCase o LCase:

    If DateValue(obj_Fichero.DateLastModified) <= DateValue(dth_Fecha) _
    And LCase(obj_FSO.GetExtensionName(obj_Fichero.Path))=”wmv” Then

    No obstante, a ver si tengo un rato y retoco el script para que permita poner patrones además de fechas.

  17. […] por urpiano on 11/10/07 Basado en un script mío anterior, este script sirve para borrar ficheros cuya fecha de última modificación sea igual o anterior a […]

  18. IT said

    Buenas días,

    Tengo un script hecho que me elimina los archivos con más de dos meses de antigüedad en una carpeta llamada Prueba (adjunto código):

    —————————————————————————————–
    Option Explicit

    Const DIAS = 60
    Const DIRECTORIO = «c:\Prueba\Log»

    Dim OBJETO, PROPIEDAD, GRUPODEARCHIVOS, ARCHIVO

    Set OBJETO = WScript.CreateObject(«Scripting.FileSystemObject»)
    Set PROPIEDAD = OBJETO.GetFolder (DIRECTORIO)
    Set GRUPODEARCHIVOS = PROPIEDAD.Files

    For Each ARCHIVO in GRUPODEARCHIVOS
    If DateDiff («d», ARCHIVO.DateCreated, Now) > DIAS Then
    ARCHIVO.Delete
    End If
    Next

    ———————————————————————————————-

    El problema viene porque la carpeta Prueba tiene subcarpetas y dicho script no funciona para éstas. ¿Alguien podría indicarme cómo hacer recursivo mi script?

    Gracias de antemano.

    Saludos

  19. urpiano said

    Para que te procese las subcarpetas, tienes que hacer el script recursivo, poniendo el cuerpo dentro de un procedimiento que se llame a sí mismo con las subcarpetas que contenga la carpeta que se recibe como parámetro:

    —————————————————————-


    Option Explicit

    Const DIAS = 60
    Const DIRECTORIO = "c:\Prueba\Log"

    Call s_BorrarFicheros(DIRECTORIO)

    Sub s_BorrarFicheros(str_Ruta)

        Dim OBJETO, PROPIEDAD, GRUPODEARCHIVOS, ARCHIVO,CARPETA

        Set OBJETO = WScript.CreateObject("Scripting.FileSystemObject")
        Set PROPIEDAD = OBJETO.GetFolder (DIRECTORIO)
        Set GRUPODEARCHIVOS = PROPIEDAD.Files

        For Each ARCHIVO in GRUPODEARCHIVOS
            If DateDiff ("d", ARCHIVO.DateCreated, Now) > DIAS Then
                ARCHIVO.Delete
            End If
        Next

        For Each CARPETA In PROPIEDAD.SubFolders

            Call s_BorrarFicheros(CARPETA.Path)

        Next

    End Sub

    —————————————————————-

    Si te fijas, esto mismo es lo que hace mi script, con lo que con una ligera modificación, puede servirte. Tú buscas la fecha en la propiedad Fecha de creación (DateCreated), mientras que mi script lo hace en la propiedad Fecha de última modificación (DateLastModified). Para que mi script lo haga con esta fecha, basta con modificar la línea:

        If DateValue(obj_Fichero.DateLastModified) <= _
                                DateValue(dth_Fecha) Then

    Por:

        If DateValue(obj_Fichero.DateCreated) <= _
                            DateValue(dth_Fecha) Then

  20. IT said

    Hola Urpiano,

    Antes de nada agradecerte tu pronta respuesta, he modificado mi script tal y como me indicaste y me ha saltado un mensaje de error de Windows Script Host, es el siguiente:

    Error: Memoria insuficiente: ‘WSCript.CreateObject’
    Código: 800A0007

    El fichero que tenía en la carpeta raíz me lo ha borrado, pero el de la subcarpeta no.

    ¿Alguna idea de por qué me salta el error?

    Gracias de antemano.

    Saludos

  21. urpiano said

    Yo creo que porque hay demasiados objetos y porque no se destruyen. Mira si así se arregla:


    Option Explicit

    Const DIAS = 60
    Const DIRECTORIO = "c:\Prueba\Log"

    Call s_BorrarFicheros(DIRECTORIO)

    Sub s_BorrarFicheros(str_Ruta)

        Dim OBJETO, PROPIEDAD, ARCHIVO, CARPETA

        Set OBJETO = WScript.CreateObject("Scripting.FileSystemObject")
        Set PROPIEDAD = OBJETO.GetFolder (DIRECTORIO)

        For Each ARCHIVO in PROPIEDAD.Files

            If DateDiff ("d", ARCHIVO.DateCreated, Now) > DIAS Then

                ARCHIVO.Delete

            End If

        Next

        For Each CARPETA In PROPIEDAD.SubFolders

            Call s_BorrarFicheros(CARPETA.Path)

        Next

        Set CARPETA = Nothing
        Set ARCHIVO = Nothing
        Set PROPIEDAD = Nothing
        Set OBJETO = Nothing

    End Sub

  22. IT said

    Hola Urpiano,

    El error se sigue produciendo y ya no sé que hacer. ¿Alguna sugerencia?

    Gracias de antemano.

    Saludos

  23. urpiano said

    :XXXXXXXXXXXXXXXXXXXXXXXXXXXXXD
    ¡¡Menuda Tontería!!

    El problema es que he llamado al parámetro que recibe el procedimiento «str_Ruta», sin embargo en el procedimiento no obtengo la carpeta str_Ruta, si no la carpeta «DIRECTORIO»; esto hace que una vez ha procesado DIRECTORIO, liste sus subcarpetas y en la llamada recursiva, siempre se obtenga la carpeta DIRECTORIO, así una y otra vez, en un bucle infinito. Basta con sustituir la línea:


    Set PROPIEDAD = OBJETO.GetFolder(DIRECTORIO)

    Por esta otra:


    Set PROPIEDAD = OBJETO.GetFolder(str_Ruta)

    No volveré a escribir código y no probarlo. No volveré a escribir código y no probarlo. No volveré a escribir código y no probarlo. No volveré a escribir código y no probarlo. No volveré a escribir código y no probarlo. No volveré a escribir código y no probarlo. No volveré a escribir código y no probarlo. No volveré a escribir código y no probarlo. No volveré a escribir código y no probarlo. No volveré a escribir código y no probarlo. No volveré a escribir código y no probarlo. No volveré a escribir código y no probarlo. No volveré a escribir código y no probarlo. No volveré a escribir código y no probarlo. No volveré a escribir código y no probarlo. No volveré a escribir código y no probarlo.

  24. IT said

    Muchísimas gracias Urpiano, ahora ya me funciona perfectamente.

    Eres un crack.

    Saludos

  25. Frantesi said

    Buenos días,

    empezaré diciendo que no tengo ni idea de scripts y agradeceré cualquier ayuda prestada.

    El caso es que necesito hacer una buena limpieza de archivos, pero no puedo basarme en la fecha de modificación. ya que algunos son solo de consulta. Necesitaría poder borrar los archivos cuya «fecha de acceso» sea más antigua que una fecha dada.

    Es posible??

    Muchas gracias de antemano por vuestra ayuda.

    Saludos cordiales

  26. tulop said

    El problema que he encontrado es que cuando el archivo en está en uso el script casca, habría de hacer para que no cascara e eliminara de forma recursiva todo el árbol de directorios seleccionado hasta terminar y saltándose los ficheros abiertos o aquellas rutas que superen los 256 caracteres.

    Muchas gracias

    • urpiano said

      Eso es sencillo:

      Option Explicit
      
      Const DIAS = 60
      Const DIRECTORIO = "c:\Prueba\Log"
      
      Call s_BorrarFicheros(DIRECTORIO)
      
      Sub s_BorrarFicheros(str_Ruta)
      
          Dim OBJETO, PROPIEDAD, ARCHIVO, CARPETA
      
          Set OBJETO = WScript.CreateObject("Scripting.FileSystemObject")
          Set PROPIEDAD = OBJETO.GetFolder (DIRECTORIO)
      
          For Each ARCHIVO in PROPIEDAD.Files
      
              If DateDiff ("d", ARCHIVO.DateCreated, Now) > DIAS Then
      
                  On Error Resume Next
                  ARCHIVO.Delete
                  On Error Goto 0
      
              End If
      
          Next
      
          For Each CARPETA In PROPIEDAD.SubFolders
      
              If Len(CARPETA.Path) < 257 Then Call s_BorrarFicheros(CARPETA.Path)
      
          Next
      
          Set CARPETA = Nothing
          Set ARCHIVO = Nothing
          Set PROPIEDAD = Nothing
          Set OBJETO = Nothing
      
      End Sub
      
      
  27. […] encontrado en https://urpiano.wordpress.com/2007/02/09/script-para-borrar-ficheros-viejos/ un script para el borrado de archivos en función de fecha. Funciona realmente […]

  28. Richard said

    Buenas tardes estimado, Saludos!

    Disculpe la molestia, tengo un script sencillo que uso desde hace tiempo, sin embargo algunos procesos han cambiado y se han creados subcarpetas, pero mi script no las elimina.

    Quería saber si me falta actualizar algún comando en mi script para realizar el borrado completo incluyendo las subcarpetas.

    Este es mi script: DeleteFilesOld.vbs

    sFolder = «G:\BackupArchive»
    iMaxAge = 30
    Set oFSO = CreateObject(«Scripting.FileSystemObject»)
    If oFSO.FolderExists(sFolder) Then
    for each oFile in oFSO.GetFolder(sFolder).Files
    If DateDiff(«d», oFile.DateLastModified, Now) > iMaxAge Then
    ‘wscript.echo «Deleting oFile.Name»
    oFile.Delete
    End If
    next
    End If

    Agradezco de antemano la ayuda que me pueda brindar,

    Saludos,

    Richard

  29. Jael said

    Hola a todos.

    Disculpen que los moleste pero quiero hacer mi script recursivo, para que borre los archivos de todas las subcarpetas del directorio principal pero no lo logro, alguien puede ayudarme?

    Dim oFSO, oFolder, sDirectoryPath
    Dim oFileCollection, oFile, sDir
    Dim iDaysOld

    sDirectoryPath = «D:\Todo»

    iDaysOld = 20

    Set oFSO = CreateObject(«Scripting.FileSystemObject»)
    Set oFolder = oFSO.GetFolder(sDirectoryPath)
    Set oFileCollection = oFolder.Files

    For each oFile in oFileCollection

    If LCase(Right(Cstr(oFile.Name), 3)) = «txt» Then

    If oFile.DateLastModified < (Date() – iDaysOld) Then
    oFile.Delete(True)
    End If

    End If
    Next

    Set oFSO = Nothing
    Set oFolder = Nothing
    Set oFileCollection = Nothing
    Set oFile = Nothing

    Muchas graicas por la ayuda…

Replica a thefame Cancelar la respuesta