Ir al contenido principal

Archivado de carpetas obsoletas.

Pongamos que eres un administrador de sistemas, y una de tus responsabilidades es administrar el servidor de ficheros de tu empresa. Pongamos también que en ese servidor de ficheros, tienes una carpeta que se llama, por ejemplo, proyectos, donde se han ido almacenando en carpetas individuales los proyectos que tu empresa ha ido realizando desde que a alguien se le ocurrió hacerlo. Supongamos que nadie, nunca, se ha molestado en archivar las carpetas de los proyectos que iban finalizando. Y supongamos por último, que el volumen de información ha ido creciendo hasta alcanzar el máximo de tamaño que tu pequeña SAN permite (2TB). En ese preciso instante te despiertas empapado en sudor pensando que todo ha sido un mal sueño. Pero a veces, solo a veces, algunos sueños pueden hacerse realidad.

El tema del archivado de información obsoleta es algo que me preocupa hace tiempo, aunque hasta ahora no he tenido tiempo de poder analizar en profundidad el problema. La principal barrera que siempre nos ha impedido realizar un archivado tradicional en cinta, es que el sistema que se utiliza para archivar en cinta, no archiva estructuras completas de carpetas, sino que analiza cada archivo y carpeta de forma individual y lo compara con el patrón de archivado que hayas definido (por fecha de modificación, de acceso, etc.). Desgraciadamente para mi, nosotros no podemos archivar de esa forma, ya que necesitamos que cuando se archiva un proyecto se archive toda la información relativa a ese proyecto de forma consistente. La gente de Microsoft ha hecho un gran trabajo al incluir de forma nativa en Windows 2008 R2 herramientas de archivado que facilitan mucho la vida del administrador, pero desgraciadamente (¿porque en informática siempre hay un desgraciadamente detrás de cada esquina?), estas herramientas no son demasiado aplicables a información obsoleta, además, habría que migrar el servidor de ficheros a Windows 2008 R2, con todo lo que ello implica.

En fin, la pregunta es: ¿Hay alguna solución para archivar carpetas completas basándonos en la última fecha de acceso? Mi aproximación al problema, como hago normalmente cuando algo se complica, es programar algo específico. En este caso, el script que he preparado comprueba todos los archivos que hay dentro de las carpetas de una ruta dada (nuestra inquietante carpeta de proyectos) e imprime el nombre de la carpeta, la ruta UNC a la carpeta y la fecha del acceso más reciente a cualquiera de los archivos contenidos en ella. El script en sí, es una modificación de un script posteado en el blog de Hey, scripting Guy! El código del script es el siguiente:

Set objFSO = CreateObject("Scripting.FileSystemObject")
objStartFolder = "C:\Scripts"

Set objFolder = objFSO.GetFolder(objStartFolder)
Wscript.Echo objFolder.Path
Set colFiles = objFolder.Files
For Each objFile in colFiles
Wscript.Echo objFile.Name
Next
Wscript.Echo

ShowSubfolders objFSO.GetFolder(objStartFolder)

Sub ShowSubFolders(Folder)
For Each Subfolder in Folder.SubFolders
Wscript.Echo Subfolder.Path
Set objFolder = objFSO.GetFolder(Subfolder.Path)
Set colFiles = objFolder.Files
For Each objFile in colFiles
Wscript.Echo objFile.Name
Next
Wscript.Echo
ShowSubFolders Subfolder
Next
End Sub


Como podéis ver, el script realiza las siguientes acciones:
•Crea un objeto FSO para trabajar con ficheros locales
•Define en una variable la carpeta que se va a examinar
•Enlaza el objeto FSO creado a la carpeta que se ha definido en la variable
•Muestra la ruta de acceso de la carpeta (como se explica en el enlace, esta ruta puede ser local, o una ruta UNC usando carpetas compartidas).
•Se introducen los ficheros que hay dentro de la carpeta en una colección para poder acceder a las propiedades de cada fichero individualmente.
•Se muestra el nombre de cada fichero
•Se llama a una función (Sub) la cual hace lo mismo que hemos comentado antes por cada subcarpeta de forma anidada. Es decir, en cada subcarpeta, la función se llama a si misma hasta que se llegue a una subcarpeta en la que no haya más carpetas.

Este script, está muy bien, pero aun así, no nos sirve para lo que nosotros queremos exactamente, por lo que le añadimos algunas líneas de código más:

On Error Resume next
Set objFSO = CreateObject("Scripting.FileSystemObject")
objStartFolder = “\\Ruta_UNC\carpeta”

fecha2 = CDate("30/11/1990 22:20:59")

ShowSubfolders objFSO.GetFolder(objStartFolder), 1, fecha2

Sub ShowSubFolders(Folder, level, fecha2)
On Error Resume next
For Each Subfolder in Folder.SubFolders
If level = 1 Then
Wscript.StdOut.write Subfolder.name & ";" & Subfolder.Path
End if
Set objFolder = objFSO.GetFolder(Subfolder.Path)
Set colFiles = objFolder.Files
For Each objFile in colFiles
If fecha <>
fecha = objFile.DateLastAccessed
End if
Next
If Err.Number <> 0 Then
fecha = Now()
Err.clear
End If
ShowSubFolders Subfolder, level + 1, fecha2
If level = 1 Then
WScript.StdOut.writeline ";" & fecha
fecha = fecha2
End If
Next
End Sub

Como podéis ver, he añadido un par de opciones:
•En primer lugar, elimino el recorrido inicial que se ha ce por la carpeta raíz, ya que ese dato no me interesa.
•Inicializo una variable de fecha, que se mantendrá constante. Se inicializa a una fecha suficientemente antigua, y para darle formato de tipo date a la variable, usamos la función CDate, que convierte la cadena de fecha al tipo de variable fecha. De este modo podemos inicializar las variables a la fecha que queramos.
•Llamamos a la función de mostrar subcarpetas y a parte del objeto folder que contiene la carpeta raíz con la que trabajamos, le pasamos 2 variables mas. La primera (pasando un uno) nos dirá el nivel de la subcarpeta con respecto a la ruta UNc que hemos definido inicialmente, lo que nos permitirá después filtrar los resultados mostrados para escribir la fecha solo en las carpetas del primer nivel y reinicializar la variable fecha a fecha2. La segunda variable es la variable Fecha2, que es constante y que hemos inicializado anteriormente a una fecha suficientemente antigua.
•Al principio de la función, comprobamos que la carpeta que estamos trabajando es de nivel 1 e imprimimos su nombre y su ruta, separados por ;
•Comprobamos fichero por fichero de cada subcarpeta que la variable fecha es mas reciente que la fecha de ultimo acceso del fichero. Si no lo es, asignamos a la variable fecha la fecha de último acceso de ese fichero. De ese modo, la variable fecha, va almacenando la fecha de acceso más reciente de cualquiera de los ficheros de la subcarpeta.
•Cuando volcamos la lista de ficheros, añadimos un if con control de errores por si hay un error (no tener acceso a la carpeta es el más común), y reseteamos la fecha de acceso al día de hoy.
•Por último, después de llamar otra vez a la función de mostrar subcarpetas, comprobamos que la carpeta con la que trabajamos es de nivel 1 y si lo es, escribimos la fecha y la reinicializamos.

Con este script obtendréis una salida de texto separado por ; que podéis exportar fácilmente a Excel y filtrar de la forma que mas os convenga. Para ello, recordad que tenéis que usar la redirección de salida desde una línea de comandos, algo así:

cscript c:\miscript > c:\salida_script.txt

Saludos a todos.

Comentarios

Entradas populares de este blog

Error id 12294, La base de datos SAM no pudo bloquear la cuenta de administrador...

Últimamente hemos estado teniendo un problema de esos que a todo administrador de sistemas le trae de cabeza... Al menos hasta que lo ha solucionado una vez. Para aquellos de vosotros que habéis llegado hasta aqui después de toparos con el en vuestro trabajo diario y no sabeis muy bien que hacer, voy a indicaros paso por paso como solucionarlo. El error consiste en el intento reptitivo de bloqueo de la cuenta de Administrador del dominio por parte de una maquina del dominio. Estos errores se generan en el registro de eventos de sistema con el id 12294 y con origen Directory-Services-SAM si es Windows 2008 o SAM si es Windows 2003 o anterior. El error en si no aunque parece grave, no debe preocuparnos tanto, ya que la cuenta de administrador de dominio nunca se bloquea. Lo que si nos molestara mas, es el hecho de que estos errores saturan nuestro log de eventos de sistema, así como el registro de seguridad del DC. El problema que nos encontramos cuando intentamos

Solucionar Error 8344 “Insufficient access rights to perform the operation.” En Azure AD connect

Ayer termine de instalar y configurar Azure AD connect. Para los que no lo sepáis, Azure AD connect es el programa que se utiliza para sincronizar objetos de tu directorio activo local con el directorio activo de azure. Podéis acceder a la estupenda documentación de Microsoft aquí. El caso es que después de terminar la configuración, estuve repasando que las primeras sincronizaciones fueran correctas cuando vi que aparecía una tarea con errores en Azure AD sync service. El fallo era el siguiente: Como podéis ver, esta tarea de export, que ya os voy diciendo que era una sincronización de contraseñas, falla por un problema de permisos. La verdad es que era un poco confuso, ya que había seguido la documentación de Microsoft para la implementación al pie de la letra y cumplido todos los prerrequisitos. ¿Se me escapaba algo? Al final, la respuesta era bastante sencilla. Este directorio activo no lo desplegué yo, así que hay algunas cosillas “heredadas”. Una de ellas es que una Unidad Organi

DNS y reenviadores condicionales...

Resulta que estamos migrando a Windows 2008 R2 para poder poner GPOs personalizadas por OU, y el otro día nos surgió un problemilla relacionado con los reenviadores condicionales del servicio DNS en 2008 (anteriormente, los teníamos en 2003 R2). Se nos paso configurar el reenvío de las peticiones de nuestro subdominio principal a nuestro dominio raíz, lo cual, teníamos hecho mediante el uso de reenviadores condicionales. Entramos en el nuevo servidor DNS para configurarlos y @_@ ¡¡no estaban!! Resulta que los amigos de Microsoft han cambiado las pestañas de opciones del servidor DNS y las han dejado así: Como podéis ver, el reenvío de peticiones basado en sufijo, ha desaparecido. Aparentemente solo se permite el reenvío global de peticiones, ¿no? Bueno, pues no, solo lo han cambiado de sitio. Con Windows 2003, cuando querías configurar el reenvío de peticiones DNS basado en dominio, tenias que hacerlo servidor por servidor, ya que la pestaña correspondiente, se encontraba dent