Programación · Lenguajes de programación
Tutorial de PowerShell para principiantes
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 regexQué 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 objectDentro 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)| Tipo | Ejemplo | Notas |
|---|---|---|
[int] | 42 | entero de 32 bits |
[double] | 3.14 | coma flotante; usa [decimal] para dinero |
[string] | "text" | las comparaciones no distinguen mayúsculas de minúsculas de forma predeterminada |
[bool] | $true, $false | variables automáticas, no palabras clave |
[datetime] | Get-Date | objeto .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" # TrueFunciones 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 messageLlama 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-TableAñ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 errorDentro 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 3Siguientes pasos
- PowerShell 101 y la documentación de PowerShell en Microsoft Learn.
Get-Help about_*en la shell, por ejemploGet-Help about_Operators; ejecuta antesUpdate-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.