Pide tu presupuesto ya!

Cómo escribir su primer script de PowerShell: automatización de limpieza de archivos

Una de las metodologías de codificación más importantes a seguir es asegurarse de conocer y gestionar cada forma en que su código puede “fluir”. Si piensa en su código como un flujo, puede bifurcarse, regresar a varios puntos y encontrar muchas condiciones.

El manejo de errores garantiza que configure “redes” o un lugar predeterminado al que pueda fluir su código cuando sucede algo inesperado.

Usemos un escenario del mundo real en el que podría encontrarse, relacionado con el manejo de errores de PowerShell.

Creación del script inicial para la limpieza de archivos

Necesitamos limpiar algunos archivos antiguos. Nuestro servidor de archivos existe desde siempre y necesitamos limpiar algo de espacio. La administración ha decidido eliminar todos los archivos que tengan más de un número de días específico. Necesitamos crear un script que busque recursivamente una carpeta, encuentre todos los archivos con una antigüedad superior a una determinada cantidad de días y los elimine.

La tarea parece bastante fácil, pero esta es la sección de manejo de errores, ¡así que sabes que algunas cosas saldrán mal!

Comencemos a comprender el manejo de errores construyendo primero el script de demostración del escenario. sin manejo de errores para demostrar el problema que resuelve el manejo de errores.

  1. Primero, abra una nueva pestaña de VS Code.

    Como ahora solo estamos intentando algunas cosas, no guardaremos el script todavía. Dígale temporalmente a VS Code que está a punto de escribir algo de PowerShell.

    Presione Ctrl-Shift-P, escriba ‘lang’, seleccione Elija el modo de idiomaescriba “poder” y elija PowerShell. Ahora VS Code sabe que escribirás PowerShell.

  2. A continuación, divida el problema en tareas, resolviendo primero la más obvia.

    En este caso, la tarea genera un comando para leer archivos en un directorio.

    Get-ChildItem -Path C:\OldForgottenFolder
    
  3. Get-ChildItem también devuelve directorios que no necesitamos, así que limitémoslo solo a archivos.

    Get-ChildItem -Path C:\OldForgottenFolder -File
    
  4. Si hay archivos en esos subdirectorios, necesitamos obtenerlos también con Recurse.

    Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse
    
  5. Ahora que tenemos el comando y los parámetros, devuelve TODOS los archivos. Sólo necesitamos encontrar aquellos que tengan más de un determinado número de días.

    Desde Get-ChildItem devuelve cada archivo con un LastWriteTime propiedad del objeto, debemos filtrar por esa propiedad. Usaremos el Where filtrar para encontrar los archivos con un LastWriteTime menos de una fecha especificada.

    (Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le ?????}
    
  6. La fecha debe ser dinámica porque lo “viejo” de hoy será diferente de lo “viejo” de mañana.

    Comente la línea anterior porque la necesitaremos en algún momento y luego averiguará la situación de la fecha.

    ## (Get-ChildItem -Path C:\\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le ?????}
    $Now = Get-Date
    $Now
    
  7. Ahora que tenemos la fecha de hoy, busquemos una cantidad específica de días antes de hoy para encontrar la fecha. solo pondré 30 Estoy aquí temporalmente porque sé que algunos archivos tienen más de cinco días para hacer una prueba rudimentaria.

    ## (Get-ChildItem -Path C:\\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le ?????}
    $Now = Get-Date
    $LastWrite = $Now.AddDays(-30)
    $LastWrite
    
  8. ¡Hecho! Juntémoslo hasta ahora.

    $Now = Get-Date
    $LastWrite = $Now.AddDays(-30)
    (Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le $LastWrite}
    

    Ahora tenemos un pequeño script que encuentra todos los archivos en un directorio que tienen más de un número específico de días.

  9. A continuación, debemos añadir la posibilidad de eliminar aquellos archivos más antiguos. Esto es trivial usando el Remove-Item cmdlet y la canalización.

    $Now = Get-Date
    $LastWrite = $Now.AddDays(-30)
    (Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le $LastWrite} | Remove-Item
    
  10. ¡Hecho! Pero espera, no tengo idea de qué archivos eliminó. También hubo algunos errores que abordaremos en unos minutos. Agreguemos algunas funciones básicas.

    $VerbosePreference="Continue"
    
    $Now = Get-Date
    $LastWrite = $Now.AddDays(-30)
    $oldFiles = (Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le $LastWrite}
    foreach ($file in $oldFiles) {
        Remove-Item -Path $file.FullName
        Write-Verbose -Message "Successfully removed [$($file.FullName)]."
    }
    
  11. Deberá incluir un bucle como este para ejecutar algún tipo de código para cada archivo. Aquí no estamos usando la canalización y en su lugar colocamos todos los archivos encontrados en un oldFiles variable, una matriz de objetos de archivo. Entonces estamos corriendo Remove-Item en cada uno como antes, pero esta vez incluye un mensaje detallado que nos dice qué archivo se está eliminando.

  12. Ahora ejecutemos este código y veamos qué sucede.

    Ahora puede ver a través del mensaje detallado que eliminó algunos archivos. El código que tenemos ahora son las agallas que necesitamos para crear el script. Ahora creemos un script real a partir de esto en la siguiente sección.

Maximizar la flexibilidad y la reutilización con parámetros

Ha creado su script, pero todavía tiene el potencial de ser flexible y reutilizable. ¿Cómo? Los parámetros nos permitirán especificar el directorio y la antigüedad de los archivos a los que queremos apuntar, haciendo que el script sea más flexible.

  1. Antes de continuar mucho más, guardemos nuestro trabajo. Llámalo Eliminar-FileOlderThan.ps1.

    Observe el formato verbo/sustantivo con un guión. Si es posible, intente crear siempre los nombres de los scripts de la misma manera que los comandos de PowerShell para lograr coherencia y legibilidad.

  2. En primer lugar, los scripts deben ser reutilizables. Lo más probable es que quieras utilizar este script en diferentes directorios y en diferentes edades. Necesitaremos introducir algunos parámetros. Para hacer eso, averiguamos qué cambiará. El directorio y el número de días. Entiendo.

    param (
        [Parameter(Mandatory)]
        [string]$FolderPath,
    [Parameter(Mandatory)]
    [int]$DaysOld
    

    )

    $Ahora = Obtener-Fecha
    $Últimaescritura = $Ahora.AddDays(-30)
    $oldFiles = (Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse).Dónde{$_.LastWriteTime -le $LastWrite}
    foreach ($archivo en $archivosantiguos) {
    Eliminar elemento -Path $file.FullName
    Write-Verbose -Mensaje "Eliminado con éxito [$($file.FullName)]".
    }

    Añadir un param bloquea en la parte superior y define cada parámetro como obligatorio ya que debemos tener una ruta y un número para que el script funcione. Además, especifique el tipo aquí como práctica recomendada.

  3. Reemplace los elementos estáticos que teníamos en el código anterior con los valores de los parámetros.

    param (
        [Parameter(Mandatory)]
        [string]$FolderPath,
    [Parameter(Mandatory)]
    [int]$DaysOld
    

    )

    $Ahora = Obtener-Fecha
    $LastWrite = $Now.AddDays(-$DaysOld)
    $oldFiles = (Get-ChildItem -Path $FolderPath -File -Recurse).Dónde{$_.LastWriteTime -le $LastWrite}
    foreach ($archivo en $archivosantiguos) {
    Eliminar elemento -Path $file.FullName
    Write-Verbose -Mensaje "Eliminado con éxito [$($file.FullName)]".
    }

  4. Ahora ejecutemos el script y veamos qué sucede.

    C:\Scripts\Remove-FileOlderThan.ps1 -FolderPath C:\OldForgottenFolder -DaysOld 30 -Verbose
    

    Puedes ver como tenemos que especificar la ruta de la carpeta y el número de días de antigüedad como parámetros. Utilice el Verbose parámetro para ver que Write-Verbose línea.

    PowerShell ejecutó el script exactamente como antes, pero ahora tenemos un script parametrizado que podemos usar en cualquier directorio o en cualquier antigüedad de archivos.

    Al observar el resultado, encontramos un texto en rojo. O no tienes derechos o el archivo es de sólo lectura. ¿Pero en qué archivos falló? ¿Y cómo se asegura de que esos archivos también se eliminen?

    Conclusión

    En este tutorial, creamos un script para limpiar archivos antiguos de un directorio, garantizando flexibilidad al agregar parámetros. Si bien el script funciona según lo previsto, vimos que aún no se había abordado el manejo de errores, lo cual es crucial cuando se trata de escenarios del mundo real.

    A medida que avancemos, agregar administración de errores nos permitirá manejar problemas, como cmdlets que arrojan errores o archivos inaccesibles, lo que nos ayudará a evitar la terminación de secuencias de comandos y brindará información detallada sobre lo que salió mal.

    ¡Estén atentos a la próxima demostración! PowerShell 101: errores de terminación, de no terminación y Try/Catch.

Written by

Leave a comment