Guía Avanzada de Automatización con PowerShell

  • Orientado a objetos: Los cmdlets no manejan texto plano, sino objetos completos (archivos, servicios, procesos). Esto permite acceder directamente a sus propiedades y métodos mediante el tubo (|).
  • Tubo basado en objetos: El flujo Get-Service | Where-Object {$_.Status -eq 'Running'} filtra servicios activos sin necesidad de parsear cadenas.
  • Nomenclatura coherente: Todos los comandos siguen el patrón Verbo-Sustantivo, como Start-Process, Stop-Service o Get-Date, lo que facilita su descubrimiento.
  • Integración con .NET: Puedes invocar clases de .NET directamente desde el script: [System.DateTime]::Now.AddDays(7).
  • Descubribilidad integrada: Usa Get-Command *item* para buscar comandos, Get-Help Get-ChildItem -Examples para ver ejemplos, y Get-Member para inspeccionar las propiedades de cualquier objeto.

2. Crear y ejecutar scripts (.ps1)

Los scripts se guardan con extensión .ps1 y pueden editarse con cualquier editor, aunque se recomienda VS Code con la extensión oficial de PowerShell.

Para ejecutar un script local:

.\MiScript.ps1

Sin embargo, es común encontrarse con restricciones por la política de ejecución:

  • Restricted: No permite ejecutar scripts (valor predeterminado en algunos sistemas).
  • RemoteSigned: Permite scripts locales, pero requiere firma digital para scripts descargados (recomendado).
  • Unrestricted: Ejecuta todos los scripts (riesgoso).

Consulta tu política actual:

Get-ExecutionPolicy

Cambiarla (requiere permisos de administrador):

Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

Alternativamente, puedes omitir temporalmente la política:

powershell.exe -ExecutionPolicy Bypass -File .\MiScript.ps1

3. Elementos esenciales del lenguaje

Variables y tipos

$nombre = "Carlos"
$contador = 100
$fecha = Get-Date
$archivos = Get-ChildItem C:\Logs

PowerShell infiere tipos automáticamente, pero también puedes declararlos explícitamente:

[int]$numero = "50"
[datetime]$inicio = "2025-04-05"

Los ámbitos disponibles son: $global:, $script:, $local:, $private:.

Operadores comunes

  • Aritméticos: + - * / %
  • Comparación: -eq (igual), -ne (distinto), -gt (mayor que), -lt, -like (comodines), -match (expresiones regulares)
  • Lógicos: -and, -or, -not
  • Especiales: .. (rango), -is (verificación de tipo), -as (conversión segura)

Estructuras de control

if ($edad -ge 18) {
    Write-Host "Acceso permitido"
} else {
    Write-Host "Acceso denegado"
}

foreach ($usuario in $listaUsuarios) {
    Write-Host "Procesando: $usuario"
}

for ($i = 0; $i -lt 10; $i++) {
    Write-Host "Iteración $i"
}

Arrays y tablas hash

$nombres = "Ana", "Luis", "Eva"
$edades = @(25, 30, 28)

$config = @{
    Puerto = 8080
    Modo = "Desarrollo"
    Activo = $true
}
Write-Host "Puerto configurado: $($config.Puerto)"

4. Funciones reutilizables

Las funciones permiten encapsular lógica compleja:

function MostrarSaludo {
    param(
        [string]$Nombre = "Usuario"
    )
    return "Hola, $Nombre!"
}

MostrarSaludo -Nombre "María"

Para funciones avanzadas, usa [CmdletBinding()] para habilitar parámetros estándar como -Verbose, -WhatIf o -Confirm:

function ProcesarArchivo {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true, ValueFromPipeline=$true)]
        [string[]]$Ruta
    )
    process {
        foreach ($ruta in $Ruta) {
            if (Test-Path $ruta) {
                [PSCustomObject]@{
                    Archivo = Split-Path $ruta -Leaf
                    TamañoKB = [Math]::Round((Get-Item $ruta).Length / 1KB, 2)
                    Fecha = (Get-Item $ruta).LastWriteTime
                }
            } else {
                Write-Warning "No se encontró: $ruta"
            }
        }
    }
}

Este ejemplo acepta entrada por tubería y genera objetos estructurados para su posterior formato.

5. Manejo robusto de errores

PowerShell distingue entre errores terminales (detienen la ejecución) y no terminales (el comando continúa).

Controla el comportamiento con -ErrorAction:

  • -ErrorAction Stop: Convierte un error no terminal en terminal.
  • -ErrorAction SilentlyContinue: Omite errores silenciosamente.

Usa bloques try/catch para capturar errores críticos:

try {
    $contenido = Get-Content "archivo.txt" -ErrorAction Stop
} catch [System.IO.FileNotFoundException] {
    Write-Error "El archivo no existe: $($_.Exception.Message)"
} catch {
    Write-Error "Error inesperado: $($_.Exception.GetType().Name)"
} finally {
    # Limpieza o cierre de recursos
}

La variable automática $Error almacena una lista de los últimos errores ocurridos.

6. Organización modular del código

Los módulos (archivos .psm1) agrupan funciones, variables y alias reutilizables. Se importan con:

Import-Module NombreDelModulo

Puedes publicar o consumir módulos desde PowerShell Gallery usando Find-Module, Install-Module.

Para cargar funciones en el ámbito actual (útil en scripts grandes), usa dot sourcing:

. .\FuncionesComunes.ps1

Esto permite que las funciones definidas en ese archivo estén disponibles directamente en el script principal.

7. Seguridad en scripts

  • Principio del mínimo privilegio: Ejecuta scripts solo con los permisos estrictamente necesarios.
  • Firma de código: Firma tus scripts con certificados digitales usando Set-AuthenticodeSignature y configura políticas como AllSigned en entornos sensibles.
  • No almacenes credenciales en texto claro: Usa Get-Credential o cifrado con Export-Clixml (solo accesible por el mismo usuario y máquina).
  • Valida todas las entradas: Nunca confíes en datos externos sin validación previa.
  • Registra operaciones: Usa Start-Transcript o Write-Log personalizados para auditoría.

8. Depuración efectiva

  • VS Code / ISE: Establece puntos de interrupción, inspecciona variables y recorre el código paso a paso.
  • Set-PSBreakpoint: Configura puntos de ruptura por línea, variable o comando.
  • Write-Debug: Inserta mensajes que solo se muestran si $DebugPreference = 'Continue'.
  • Out-GridView: Visualiza objetos complejos en una tabla interactiva.
  • $PSBoundParameters: Revisa qué parámetros fueron pasados a una función.

9. Temas avanzados

  • Trabajos en segundo plano: Start-Job permite ejecutar tareas de forma asíncrona.
  • Tareas programadas: Usa Register-ScheduledJob o el Planificador de tareas para automatizar ejecuciones.
  • Administración remota: Invoke-Command -ComputerName PC01 { Get-Process } ejecuta comandos en máquinas remotas (requiere WinRM o SSH).
  • Clases (v5+): Define tus propias clases para programación orientada a objetos.
  • PowerShell 7+: Versión multiplataforma (Windows, Linux, macOS), más rápida y moderna que Windows PowerShell.

10. Recursos recomendados

  • Documentación oficial: Microsoft Learn - PowerShell
  • Libros: "PowerShell in Depth", "Learn PowerShell in a Month of Lunches"
  • Comunidades: Stack Overflow ([powershell]), Reddit (/r/PowerShell), GitHub
  • Galerías: PowerShell Galllery para módulos compartidos.

PowerShell es una herramienta esencial para automatizar tareas administrativas, DevOps y desarrollo interno. Dominar sus conceptos clave —como el manejo de objetos, funciones avanzadas, tratamiento de errores y seguridad— permite crear soluciones robustas, mantenibles y escalables. La práctica constante y el uso de buenas prácticas garantizan scripts eficaces y seguros.

Etiquetas: PowerShell automatización scripting .NET DevOps

Publicado el 9-15 22:39