Pipelines I: PowerShell declarativo
Metadatos de la lección
- Autoría:
- Ignacio Slater-Muñoz
- Última actualización:
- 27 de marzo de 2026
Cambios recientes:
-
8880728· 27 de marzo de 2026 · ✨ feat(notes): add abstract slots and Python structured-output lesson ( GitLab / GitHub ) -
0b7190d· 26 de marzo de 2026 · 📚🐛 feat(scripting): add Nushell pipelines lesson and unblock checks ( GitLab / GitHub ) -
4443cc6· 12 de marzo de 2026 · ✨♻️ feat(references): refine catalog-driven bibliography rendering ( GitLab / GitHub )
Abstract
En PowerShell, el pipeline es un modelo de trabajo orientado a objetos: cada cmdlet recibe datos estructurados, los procesa y entrega resultados al siguiente paso.
En esta lección practicarás cómo componer pipelines declarativos para filtrar, proyectar y transformar datos, manteniendo el foco en el flujo de objetos desde la fuente hasta la salida.
Pensar en pasos: de colecciones al pipeline de PowerShell
Antes de hablar del pipeline, observemos cómo procesamos colecciones en otros paradigmas. En muchos lenguajes (funcionales, orientados a objetos o incluso SQL), aplicamos una secuencia de transformaciones: filtrar, transformar y limitar.
Transformaciones encadenadas
Una transformación recibe una entrada y produce una salida. Al encadenarlas, describes qué quieres hacer con los datos (flujo), no cómo recorrerlos (bucle).
Mismo flujo, distintos lenguajes
users // : List[User]
.filter(_.active) // : List[User]
.map(_.email) // : List[String]
.distinct // : List[String]
.take(10) // : List[String]list(
islice(
dict.fromkeys(
map(
lambda u: u.email,
filter(
lambda u: u.active,
users # <class 'list'>
) # <class 'filter'>
) # <class 'map'>
), # <class 'dict'>
10
) # <class 'itertools.islice'>
) # <class 'list'>SELECT DISTINCT email
FROM users
WHERE active = TRUE
LIMIT 10;Algunos lenguajes hacen estas transformaciones más explícitas y legibles que otros. En este ejemplo, Python mantiene el mismo modelo mental, pero con una carga sintáctica mayor.
Aunque la sintaxis cambia, la idea es siempre la misma:
Estás describiendo una cadena de transformaciones sobre un flujo de datos.
- Quedarse solo con los elementos que cumplen una condición.
- Extraer un dato relevante de cada elemento.
- Eliminar duplicados.
- Limitar la cantidad de resultados.
Puedes imaginarlo como una cadena de transformaciones:
datos -> filtrar -> proyectar -> eliminar duplicados -> limitar.
¿Dónde entra PowerShell?
El pipeline de PowerShell expresa exactamente la misma idea, pero en lugar de encadenar métodos o funciones, conecta comandos que procesan objetos.
Cada comando:
- Streaming: cada objeto fluye hacia el siguiente comando en cuanto está disponible (no espera a evaluar toda la colección).
- Operador
: conecta la salida de un cmdlet con la entrada del siguiente.||
El mismo flujo expresado como pipeline
Import-Csv users.csv |
Where-Object { $_.active -eq 'true' } |
Select-Object -ExpandProperty email |
Sort-Object -Unique |
Select-Object -First 10 Detalles clave
-
conecta pasos: no es “texto” — son objetos tipados los que fluyen entre comandos.|| - Filtrar temprano: igual que en SQL o FP, reduces trabajo en los pasos siguientes del pipeline.
- Procesamiento incremental: PowerShell no necesita cargar todo en memoria para empezar a trabajar.
- El último comando decide cómo se muestran los resultados.
Cmdlets comunes en el pipeline
Una vez que entiendes el pipeline como una secuencia de transformaciones, el siguiente paso es conocer los cmdlets más comunes que aparecen en casi cualquier flujo de PowerShell.
No se trata de memorizar comandos, sino de reconocer roles: filtrar, transformar, ordenar, limitar y proyectar datos.
Filtrar objetos
Get-Process | Where-Object { $_.CPU -gt 100 } CPU CPU representa el tiempo
total de CPU consumido por el proceso (en segundos), no un porcentaje de
uso. Detalles clave
-
es un cmdlet de origen : consulta al sistema operativo y produce un flujo de objetos, uno por cada proceso en ejecución.Get-ProcessGet-Process -
recibe los objetos del pipeline uno a uno y evalúa una condición booleana para cada uno.Where-ObjectWhere-Objectno modifica los objetos: decide cuáles continúan en el pipeline y cuáles se descartan.Where-ObjectWhere-Object - Dentro del bloque
, la variable automática{ ... }{ ... }representa el objeto actual que está pasando por el pipeline. En este ejemplo,$_$_es un objeto de tipo$_$_.[System.Diagnostics.Process][System.Diagnostics.Process]
Conceptualmente, este paso equivale a un filter en programación
funcional o a una cláusula en SQL: describe qué procesos te interesan, no cómo recorrer la colección de procesos
manualmente.
WHERE WHERE
Proyectar y limitar
Get-Service | Select-Object -Property Name, Status -First 10 Detalles clave
-
es un cmdlet de origen que consulta al sistema operativo y produce un flujo de objetos, uno por cada servicio.Get-ServiceGet-Service -
es el cmdlet principal para proyectar datos en el pipeline: permite elegir qué propiedades de cada objeto se mantienen en el resultado que continúa fluyendo en el pipeline.Select-ObjectSelect-Object- La opción
indica que solo nos interesan esas dos propiedades. El resultado no es el objeto original, sino un nuevo objeto que contiene únicamente esas propiedades. En la mayoría de los casos, PowerShell crea un objeto de tipo-Property Name, Status-Property Name, Status.[PSCustomObject][PSCustomObject] - La opción
limita el número de objetos que continúan fluyendo en el pipeline. Una vez alcanzado ese límite, el pipeline deja de producir más objetos. Esto es equivalente a un-First 10-First 10en SQL. Limitar resultados temprano en el pipeline puede reducir el trabajo de los comandos siguientes.LIMITLIMIT
-
Conceptualmente, este paso equivale a: en SQL, o a un SELECT Name, Status FROM services LIMIT 10SELECT Name, Status FROM services LIMIT 10map que extrae solo ciertas propiedades de cada
objeto en programación funcional. De nuevo, describes qué quieres obtener
de cada objeto, no cómo recorrer la colección manualmente.
Proyectar vs expandir propiedades
no solo cambia cómo se
muestran los datos: también puede transformar la estructura del objeto que
continúa fluyendo en el pipeline.
Select-Object Select-Object
-
mantiene un objeto proyectado con la propiedad seleccionada.Select-Object -Property NameSelect-Object -Property Name -
expande la propiedad y emite su valor directamente.Select-Object -ExpandProperty NameSelect-Object -ExpandProperty Name
Ejemplo
Get-Service |
Select-Object -First 2 -Property Name |
Format-ListName: AppMgmt
Name: AppVClientGet-Service |
Select-Object -First 2 -ExpandProperty Name |
Format-ListAppMgmt
AppVClient
En el primer caso, el pipeline sigue transportando objetos con una
propiedad . En el segundo caso, el
pipeline emite directamente los valores de esa propiedad (cadenas de
texto).
Name Name
Transformar con ForEach-Object ForEach-Object
ForEach-Object ForEach-Object
Mientras solo elige o expande
propiedades existentes, Select-Object Select-Object permite
crear nuevos datos a partir de cada objeto (similar a ForEach-Object ForEach-Object map).
Get-ChildItem -Path . -File -Filter *.mp4 |
ForEach-Object {
[PSCustomObject]@{
Name = $_.Name
SizeKB = [math]::Round($_.Length / 1KB, 2)
}
} |
Sort-Object -Property SizeKB -Descending |
Select-Object -First 10 Detalles clave
-
produce un flujo de objetos del sistema de archivos (como instancias deGet-ChildItemGet-ChildItem). Aquí limitamos a archivos con[FileInfo][FileInfo]y al patrón-File-File.-Filter *.mp4-Filter *.mp4 -
aplica un bloque a cada objeto del pipeline. Conceptualmente, se parece aForEach-ObjectForEach-Objectmapen programación funcional: por cada objeto que entra al pipeline, el bloque produce un resultado que continúa fluyendo. PowerShell ejecuta este bloque a medida que los objetos van llegando al pipeline; no necesita esperar a que toda la colección esté disponible. - Dentro del bloque,
vuelve a representar el objeto actual (en este caso, un archivo). Usamos sus propiedades$_$_yNameNamepara calcular el tamaño enLengthLengthy construir una representación más útil del archivo.KBKB - El bloque devuelve un
, es decir, un objeto nuevo con propiedades explícitas. Esto mantiene el pipeline estructurado: los comandos siguientes reciben objetos con propiedades claras, en lugar de tener que interpretar texto.[PSCustomObject][PSCustomObject] - Composición: observa cómo el pipeline fluye de la transformación hacia el ordenamiento y finalmente a la limitación.
Ejercicio:
Transformar datos JSON con pipelines
Requisitos
Un uso común de PowerShell es el procesamiento y análisis de datos, especialmente en tareas de exploración y análisis de datos. Para eso necesitas poder leer y escribir objetos (serialización) en formatos estándar como JSON, CSV o XML. PowerShell incluye cmdlets que serializan y deserializan datos y que se integran naturalmente con el pipeline.
En este ejercicio practicarás un flujo típico: «texto → objetos → transformaciones → texto» . La regla es simple: trabaja con objetos hasta el último paso y solo convierte a texto cuando necesites escribir o exportar datos.
Supón que tienes un archivo users.json con una lista de usuarios con
esta estructura:
[
{ "name": "Isaac", "email": "isaac@example.com", "active": true },
{ "name": "Miria", "email": "miria@example.com", "active": false }
]Tu tarea es:
- Filtrar solo los usuarios con
activeen true. - Transformar cada usuario a un objeto con solo
nameyemail, ambos en mayúsculas. - Guardar el resultado en un nuevo archivo
active-users.json.
Notas
-
toma texto JSON y lo convierte en objetos de PowerShell con propiedades accesibles.ConvertFrom-JsonConvertFrom-Json -
serializa objetos de PowerShell y produce texto JSON. En estructuras anidadas puede ser necesario aumentar la profundidad conConvertTo-JsonConvertTo-Json.-Depth-Depth -
escribe texto en un archivo (creándolo o reemplazándolo).Set-ContentSet-Content
Uso esperado
Get-Content 'users.json' -Raw |
ConvertFrom-Json |
... | # Tu código aquí: filtra y transforma objetos
ConvertTo-Json |
Set-Content 'active-users.json' Solución
Get-Content 'users.json' -Raw |
ConvertFrom-Json |
Where-Object { $_.active } |
ForEach-Object {
[PSCustomObject]@{
name = $_.name.ToUpper()
email = $_.email.ToUpper()
}
} |
ConvertTo-Json -Depth 3 |
Set-Content 'active-users.json'Este pipeline lee el archivo como texto, lo convierte a objetos, aplica filtrado y transformación, vuelve a serializar a JSON, y finalmente guarda el resultado. El flujo principal es filtrar → transformar → serializar. El trabajo principal ocurre sobre objetos, no sobre strings.
Conclusiones
El pipeline de PowerShell no es solo sintaxis: es una forma de diseñar soluciones basada en etapas de transformación. Cada etapa toma objetos con propiedades claras y produce nuevos resultados que continúan fluyendo.
Pensar en roles (filtrar, proyectar, transformar, ordenar y limitar) ayuda a separar intención y mecanismo: primero defines qué resultado necesitas, luego dejas que el pipeline resuelva cómo recorrer los datos.
Puntos clave
- El pipeline transporta objetos tipados, no texto.
- Filtra temprano con
para reducir el trabajo en los pasos siguientes.Where-ObjectWhere-Object - Proyecta lo necesario con
y limita conSelect-ObjectSelect-Objectcuando puedas.-First-First - Transforma con
para construir objetos derivados a partir de cada entrada.ForEach-ObjectForEach-Object - Decide el formato al final: exporta/serializa solo en la última etapa.
¿Qué nos llevamos?
Diseñar pipelines claros mejora la calidad técnica del trabajo: facilita leer, mantener y validar cada etapa de procesamiento.
Como criterio práctico, conserva la regla central de la lección: trabaja con objetos durante el pipeline y convierte a texto solo cuando necesites serializar o exportar resultados.
Comparativas y otros ecosistemas
¿Con ganas de más?
Referencias recomendadas
- “The pipeline: Connecting commands” (pp. 69-83) en Learn PowerShell in a month of lunches, fourth edition: Covers Windows, Linux, and MacOS por Travis PlunkCapítulo introductorio sobre el pipeline de PowerShell: cómo encadenar cmdlets, por qué el flujo de objetos es distinto al de shells tradicionales, y cómo exportar resultados a CSV/JSON/XML. Incluye ejemplos prácticos con
, conceptos de conversión y exportación, y ejercicios guiados para afianzar el uso del pipeline.Get-ProcessGet-Process
Referencias adicionales
- “ Collection Pipeline ” en martinfowler.com por Martin FowlerArtículo fundacional sobre el patrón Collection Pipeline: cómo encadenar operaciones declarativas (
map,filter,reduce,group-by) para transformar colecciones. Compara sintaxis en múltiples lenguajes (Ruby, Clojure, Smalltalk), explora alternativas (loops, comprehensions), y discute temas avanzados como laziness, paralelismo e inmutabilidad. Incluye un catálogo detallado de operaciones comunes con ejemplos visuales.