cv.cm

Programación · Lenguajes de programación

Tutorial de PowerShell para principiantes

7 min de lectura

Respuesta corta

PowerShell es la shell y el lenguaje de scripting multiplataforma de Microsoft para automatizar tareas. Sus comandos, llamados cmdlets, pasan objetos .NET por la canalización en lugar de texto plano, así que puedes filtrar, ordenar y exportar datos sin analizar texto. Esta página cubre la instalación de PowerShell 7, la ejecución de scripts, los cmdlets, las variables, los operadores, el control de flujo, las funciones, las colecciones y el manejo de errores.

Abrir Probador de regex

Qué es PowerShell y para qué se usa

PowerShell es una shell y un lenguaje de scripting multiplataforma de Microsoft, construido sobre .NET. A diferencia de las shells tradicionales, que pasan texto plano entre comandos, PowerShell pasa objetos .NET con propiedades y métodos, de modo que puedes filtrar y ordenar datos sin analizar texto.

Los administradores de sistemas y los ingenieros DevOps usan PowerShell para automatizar Windows, administrar Active Directory, Microsoft 365 y Azure, y escribir scripts de compilación y despliegue. Hay dos ediciones: Windows PowerShell 5.1, incluida en Windows, y PowerShell 7 y posteriores (el comando se llama pwsh), que es de código abierto y funciona en Windows, Linux y macOS. Este tutorial se centra en PowerShell 7.

Instala PowerShell y ejecuta Hola, mundo

En Windows, instala PowerShell 7 con winget install --id Microsoft.PowerShell --source winget; en macOS y Linux, usa Homebrew o el gestor de paquetes descrito en la guía de instalación de Microsoft. Los scripts son archivos de texto con la extensión .ps1.

# hello.ps1
Write-Output "Hello, world!"
pwsh ./hello.ps1
# Hello, world!

En Windows, la política de ejecución puede bloquear los scripts. Set-ExecutionPolicy -Scope CurrentUser RemoteSigned permite tus propios scripts locales y sigue exigiendo que los scripts descargados estén firmados. Visual Studio Code con la extensión de PowerShell es el editor recomendado.

Cmdlets y la canalización

Los comandos se llaman cmdlets y siguen el patrón de nombre Verb-Noun, como Get-Process, Set-Location o New-Item. Tres cmdlets te ayudan a explorar todo lo demás: Get-Command, Get-Help y Get-Member.

Get-Command -Noun Process          # list commands that work with processes
Get-Help Get-ChildItem -Examples   # show usage examples

# five processes using the most memory
Get-Process |
    Sort-Object -Property WorkingSet64 -Descending |
    Select-Object -First 5 -Property Name, Id, WorkingSet64

# files larger than 1 MB in the current folder
Get-ChildItem -File | Where-Object { $_.Length -gt 1MB } |
    ForEach-Object { "{0}  {1:N0} KB" -f $_.Name, ($_.Length / 1KB) }

Get-Date | Get-Member -MemberType Property   # inspect an object

Dentro de un bloque de script, $_ (o $PSItem) es el objeto actual de la canalización. Como los objetos conservan sus tipos, Sort-Object ordena los números numéricamente y las fechas cronológicamente sin trabajo adicional.

Variables y tipos

Las variables empiezan con $. Pueden contener cualquier objeto .NET y puedes añadir una restricción de tipo entre corchetes. Las cadenas entre comillas dobles expanden variables y expresiones $( ); las cadenas entre comillas simples son literales.

$name = "Ada"
[int]$count = 3
$price = 19.99                      # System.Double
$isAdmin = $false
$today = Get-Date

"Hello, $name"                      # Hello, Ada
"Next: $($count + 1)"               # Next: 4
'No $expansion here'                # No $expansion here
$price.GetType().Name               # Double
$today.ToString("yyyy-MM-dd")       # for example 2026-10-31
[int]"42" + 1                       # 43 (explicit conversion)
TipoEjemploNotas
[int]42entero de 32 bits
[double]3.14coma flotante; usa [decimal] para dinero
[string]"text"las comparaciones no distinguen mayúsculas de minúsculas de forma predeterminada
[bool]$true, $falsevariables automáticas, no palabras clave
[datetime]Get-Dateobjeto .NET DateTime completo
[array], [hashtable]@(1, 2), @{ a = 1 }colecciones, que se explican más abajo

Operadores y control de flujo

Los operadores de comparación son palabras, no símbolos: -eq, -ne, -gt, -lt, -ge, -le, -like (comodines), -match (expresiones regulares) y -contains. Las comparaciones de cadenas no distinguen mayúsculas de minúsculas, salvo que uses las versiones con c, como -ceq.

$temp = 22
if ($temp -gt 30) {
    "hot"
} elseif ($temp -ge 15) {
    "mild"                           # mild
} else {
    "cold"
}

switch ("report.csv") {
    { $_ -like "*.csv" } { "CSV file" }    # CSV file
    { $_ -like "*.txt" } { "text file" }
    default { "other" }
}

foreach ($n in 1..3) { "n = $n" }          # n = 1, n = 2, n = 3
for ($i = 0; $i -lt 2; $i++) { "i = $i" }  # i = 0, i = 1
$k = 3
while ($k -gt 0) { $k-- }
"Hello" -eq "hello"                        # True

Funciones y parámetros

Las funciones usan bloques param() para declarar parámetros con tipo y nombre. Añadir [CmdletBinding()] da a una función los mismos parámetros comunes que los cmdlets integrados, como -Verbose. Cualquier salida que no se capture se convierte en el valor de retorno de la función.

function Get-Greeting {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string]$Name,
        [string]$Greeting = "Hello"
    )
    Write-Verbose "Building greeting for $Name"
    "$Greeting, $Name!"
}

Get-Greeting -Name "Ann"                  # Hello, Ann!
Get-Greeting -Name "Bo" -Greeting "Hi"    # Hi, Bo!
Get-Greeting "Cy" -Verbose                # also prints the verbose message

Llama a las funciones como a los cmdlets, con espacios entre los argumentos: Get-Greeting -Name Ann. Escribir Get-Greeting("Ann", "Hi") pasa un único argumento de tipo arreglo, una sorpresa frecuente para quienes vienen de otros lenguajes.

Arreglos, hashtables y objetos personalizados

Los arreglos se crean con @( ) o con una lista separada por comas. Las hashtables, escritas @{ }, almacenan pares clave-valor. [pscustomobject] convierte una hashtable en un objeto que funciona bien con Sort-Object, Format-Table y Export-Csv.

$langs = @("PowerShell", "Python")
$langs += "Go"                       # creates a new, longer array
$langs.Count                         # 3
$langs[0]                            # PowerShell
$langs -contains "Go"                # True

$ports = @{ http = 80; https = 443 }
$ports["ssh"] = 22
$ports.https                         # 443
$ports.Keys.Count                    # 3

$user = [pscustomobject]@{ Name = "Ann"; Age = 31 }
$user.Name                           # Ann
$people = @(
    [pscustomobject]@{ Name = "Bo"; Age = 25 }
    $user
)
$people | Sort-Object Age | Format-Table

Añadir a un arreglo con += copia todo el arreglo cada vez. En bucles grandes, recoge directamente la salida del bucle ($result = foreach (...) { ... }) o usa un [System.Collections.Generic.List[object]].

Manejo de errores

PowerShell tiene errores terminantes, que detienen la ejecución, y errores no terminantes, que muestran un mensaje y continúan. try/catch/finally solo captura errores terminantes, así que añade -ErrorAction Stop a un cmdlet cuando quieras capturar sus fallos.

try {
    $content = Get-Content -Path "missing.txt" -ErrorAction Stop
}
catch [System.Management.Automation.ItemNotFoundException] {
    Write-Warning "File not found: $($_.Exception.Message)"
}
catch {
    Write-Error "Unexpected error: $_"
}
finally {
    "cleanup done"
}

$ErrorActionPreference = "Stop"   # make all errors terminating in this script
throw "Something went wrong"      # raise your own terminating error

Dentro de catch, $_ es el registro del error. Establecer $ErrorActionPreference = "Stop" al principio de un script es una forma habitual de fallar rápido.

Un script pequeño y completo: informe de uso de disco

Este script lista los archivos más grandes de una carpeta, los agrupa por extensión y exporta un informe en CSV. Combina parámetros, la canalización, propiedades calculadas y manejo de errores.

# report.ps1
param(
    [string]$Path = ".",
    [int]$Top = 5
)
$ErrorActionPreference = "Stop"

$files = Get-ChildItem -Path $Path -File -Recurse

"Largest $Top files:"
$files | Sort-Object Length -Descending | Select-Object -First $Top |
    Format-Table Name, @{ Name = "SizeKB"; Expression = { [math]::Round($_.Length / 1KB, 1) } }

$byExt = $files | Group-Object Extension | ForEach-Object {
    [pscustomobject]@{
        Extension = if ($_.Name) { $_.Name } else { "(none)" }
        Files     = $_.Count
        TotalMB   = [math]::Round(($_.Group | Measure-Object Length -Sum).Sum / 1MB, 2)
    }
} | Sort-Object TotalMB -Descending

$byExt | Format-Table
$byExt | Export-Csv -Path "usage.csv" -NoTypeInformation
"Report saved to usage.csv"
pwsh ./report.ps1 -Path ~/Documents -Top 3

Siguientes pasos

  • PowerShell 101 y la documentación de PowerShell en Microsoft Learn.
  • Get-Help about_* en la shell, por ejemplo Get-Help about_Operators; ejecuta antes Update-Help.
  • La PowerShell Gallery, el repositorio oficial de módulos, que se usa con Install-Module.
  • PSScriptAnalyzer, un linter que revisa los scripts según las prácticas recomendadas.

Preguntas frecuentes

¿Cuál es la diferencia entre PowerShell y Windows PowerShell?

Windows PowerShell 5.1 es la edición más antigua, incluida en Windows y basada en .NET Framework. PowerShell 7 y posteriores es la edición multiplataforma y de código abierto basada en el .NET moderno, y se inicia con el comando pwsh.

¿PowerShell es lo mismo que el Símbolo del sistema?

No. El Símbolo del sistema (cmd.exe) ejecuta comandos por lotes y pasa texto. PowerShell es un lenguaje de scripting completo que pasa objetos, aunque también puede ejecutar la mayoría de los programas de línea de comandos.

¿PowerShell funciona en Linux y macOS?

Sí. PowerShell 7 y posteriores funciona en Windows, Linux y macOS, aunque algunos módulos específicos de Windows solo están disponibles en Windows.

¿Por qué no puedo ejecutar mi script .ps1?

Es posible que la política de ejecución de Windows lo bloquee. Ejecuta Set-ExecutionPolicy -Scope CurrentUser RemoteSigned e inicia los scripts con una ruta, como ./script.ps1.

¿Qué significa $_ en PowerShell?

$_ (también $PSItem) es el objeto actual de la canalización; se usa dentro de bloques de script de cmdlets como Where-Object y ForEach-Object, y dentro de catch es el error actual.

Todos los tutoriales de programación