Una vez que te acostumbras a escribir scripts de PowerShell, necesitas aprender sobre la modularización del código. La modularización es simplemente una palabra elegante para crear código en bloques de construcción. En el mundo de PowerShell, las funciones de PowerShell son una de las mejores formas de hacer esto.
Cuando escribes un script de PowerShell, tienes muchas opciones sobre cómo escribir el código. Podrías escribir mil líneas de código que realicen cientos de tareas, todo en un único bloque de código ininterrumpido. Eso sería un desastre. En cambio, deberías escribir funciones.
Las funciones aumentan drásticamente la usabilidad y legibilidad de tu código, haciéndolo mucho más fácil de trabajar. En este tutorial, aprenderás a escribir funciones, agregar y gestionar los parámetros de tus funciones, y configurar funciones para aceptar entrada de canalización. Pero primero, veamos un poco de terminología.
Este artículo fue extraído de mi libro PowerShell para Administradores de Sistemas: Automatización de Tareas Simplificada. Si aprendes algo en este tutorial, asegúrate de consultar el libro para aprender más sobre funciones y muchas otras características geniales de PowerShell.
Funciones vs Cmdlets
**Traducción al Español:**
El concepto de una función puede sonar familiar porque suena un poco como los cmdlets que probablemente ya hayas estado utilizando. Comandos como Start-Service
y Write-Host
, por ejemplo, son similares a funciones. Estos son fragmentos de código con nombres que resuelven un problema único. La diferencia entre una función y un cmdlet radica en cómo se construye cada uno de estos elementos.
A cmdlet isn’t written with PowerShell. It’s written in another language, typically something like C#. The cmdlet is then compiled and made available inside PowerShell.
Las funciones, por otro lado, están escritas en PowerShell; no en otro lenguaje.
Puedes ver qué comandos son cmdlets y cuáles son funciones utilizando el cmdlet Get-Command
y su parámetro CommandType
, como se muestra a continuación
Este comando devuelve todas las funciones cargadas actualmente en tu sesión de PowerShell o dentro de módulos disponibles para PowerShell.
Relacionado: Comprender y Construir Módulos de PowerShell
Prerrequisitos
Si deseas seguir todos los ejemplos, asegúrate de tener una versión de PowerShell disponible. No hay requisitos específicos de versión para este tutorial. Además, asegúrate de tener un buen editor de código como Visual Studio Code para copiar, pegar y ejecutar algunos fragmentos de código.
Construyendo una Función Simple
Antes de poder usar una función, necesitas definirla. Para definir una función, utilizas la palabra clave `function`, seguida de un nombre descriptivo definido por el usuario, y luego un conjunto de llaves. Dentro de las llaves hay un bloque de comandos que quieres que PowerShell ejecute.
A continuación puedes ver una función básica y cómo ejecutar esa función. Esta función se llama Install-Software
, utiliza Write-Host
para mostrar un mensaje en la consola. Una vez definida, puedes usar el nombre de esta función para ejecutar el código dentro de su bloque de comandos.
Nombrando con Verbo-Sustantivo
A function’s name is important. You can name your functions whatever you want, but the name should always describe what the function does. The function-naming convention in PowerShell is the Verb-Noun syntax.
Siempre deberías comenzar el nombre de una función con un verbo seguido de un guión y un sustantivo. Para encontrar la lista de verbos “aprobados”, utiliza el cmdlet Get-Verb
.
Cambiando el Comportamiento de la Función
Si deseas cambiar el comportamiento de una función, simplemente puedes cambiar el código que la función ejecuta como se muestra a continuación.
Ahora que has cambiado el código dentro de la función, mostrará un mensaje ligeramente diferente.
Definiendo una Función Avanzada
Puedes definir funciones en muchos lugares diferentes. En la sección anterior, el tutorial asume que simplemente copiaste y pegaste el código directamente en la consola de PowerShell. Pero esta no es la única forma. También puedes definir funciones en un script.
En la sección anterior, estabas trabajando con una función pequeña, por lo que definirla en la consola no fue un gran problema. Sin embargo, la mayoría de las veces tendrás funciones mucho más grandes. Será más fácil definir esas funciones en un script o un módulo y luego llamar a ese script o módulo para cargar la función en la memoria.
Como puedes imaginar, volver a escribir una función más extensa cada vez que quieras ajustar su funcionalidad podría resultar un poco frustrante.
I suggest you now open your favorite editor and store the function in a .ps1 file as you work through the rest of the tutorial.
Agregar parámetros a las funciones
Las funciones en PowerShell pueden tener cualquier número de parámetros. Cuando creas tus propias funciones, tendrás la opción de incluir parámetros y decidir cómo funcionarán. Los parámetros pueden ser obligatorios u opcionales, y pueden aceptar cualquier cosa o estar obligados a aceptar uno de una lista limitada de argumentos posibles.
Relacionado: Todo lo que siempre quisiste saber sobre los parámetros en PowerShell
Por ejemplo, el software ficticio que estás instalando a través de la función Install-Software
podría tener muchas versiones. Pero actualmente, la función Install-Software
no ofrece al usuario una forma de especificar qué versión desea instalar.
Si fueras el único que usa la función, podrías cambiar el código dentro de ella cada vez que quisieras una versión específica, pero eso sería una pérdida de tiempo. Este proceso también sería propenso a posibles errores, sin mencionar que deseas que otros puedan utilizar tu código.
La introducción de parámetros en tu función le permite tener variabilidad. Así como las variables te permitieron escribir scripts que podían manejar muchas versiones de la misma situación, los parámetros te permiten escribir una única función que haga una cosa de muchas maneras.
En este caso, quieres que instale versiones de la misma pieza de software y lo haga en muchas computadoras.
Vamos a agregar primero un parámetro a la función que te permita a ti o a un usuario especificar la versión a instalar.
Creando un Parámetro Simple
Crear un parámetro en una función requiere un bloque param
. El bloque param
contiene todos los parámetros de la función. Define un bloque param
con la palabra clave param
seguida de paréntesis como se muestra a continuación.
En este punto, la funcionalidad real de tu función no ha cambiado en absoluto. Solo has instalado la fontanería, preparando la función para un parámetro.
Por ahora, la función no está instalando realmente ningún software. Solo está utilizando el cmdlet
Write-Host
para simular la instalación de software para que puedas concentrarte en escribir la función.
Una vez que hayas agregado el bloque param
, puedes crear el parámetro colocándolo dentro de los paréntesis del bloque param
como se muestra a continuación.
Dentro del bloque param
anterior, primero definirías el bloque de parámetro. Usar el bloque Parameter()
de esta manera lo convertirá en un “parámetro avanzado”. Un bloque de parámetro vacío como el que ves aquí no hace nada, pero es necesario; explicaré cómo usarlo en la siguiente sección.
Vamos a centrarnos en cambio en el tipo [string]
delante del nombre del parámetro. Al colocar el tipo del parámetro entre corchetes antes del nombre de la variable del parámetro, estás convirtiendo el valor del parámetro a un tipo específico. PowerShell siempre intentará convertir cualquier valor que se pase a este parámetro en una cadena, si no lo es ya. Arriba, cualquier cosa pasada como $Version
siempre se tratará como una cadena.
Convertir tu parámetro a un tipo no es obligatorio, pero lo recomiendo encarecidamente. Define explícitamente el tipo y reducirá significativamente los errores en el futuro.
También añades $Version
a tu declaración de Write-Host
ahora. Esto significa que cuando ejecutes la función Install-Software
con el parámetro Version
y le pases un número de versión, deberías obtener una declaración que lo indique como se muestra a continuación.
Vamos a ver qué puedes hacer con este parámetro ahora.
El Atributo de Parámetro Obligatorio
Puedes usar el bloque de Parámetro para controlar varios atributos del parámetro, lo que te permitirá cambiar el comportamiento del parámetro. Por ejemplo, si quieres asegurarte de que cualquiera que llame a la función tenga que pasar un parámetro dado, podrías definir ese parámetro como Obligatorio.
Por defecto, los parámetros son opcionales. Vamos a forzar al usuario a pasar una versión usando la palabra clave Obligatorio dentro del bloque de Parámetro como se muestra a continuación.
Si ejecutas la función anterior, deberías obtener el siguiente mensaje:

Una vez que has establecido el atributo Obligatorio, ejecutar la función sin el parámetro detendrá la ejecución hasta que el usuario ingrese un valor. La función ahora espera hasta que el usuario especifique un valor para el parámetro Versión
. Una vez ingresado, PowerShell ejecuta la función.
Para evitar el mensaje de parámetro obligatorio, simplemente pasa un valor al parámetro al llamar a la función como se muestra a continuación.
Valores de Parámetro por Defecto
Si, por ejemplo, te encuentras pasando el mismo valor para un parámetro una y otra vez, puedes definir un valor de parámetro por defecto. Los parámetros por defecto son útiles cuando esperas un cierto valor para un parámetro la mayoría de las veces.
Por ejemplo, si quieres instalar la versión 2 de este software el 90 por ciento del tiempo, y preferirías no tener que establecer el valor cada vez que ejecutas esta función, podrías asignar un valor por defecto de 2 al parámetro $Versión
. Puedes ver este ejemplo a continuación.
Tener un parámetro por defecto no impide que pases uno. Tu valor pasado sobrescribirá el valor por defecto.
Agregando Atributos de Validación de Parámetros
Siempre es una buena idea limitar qué valores puedes pasar a una función a través de parámetros. La mejor manera de hacerlo es con atributos de validación de parámetros.
Limitar la información que los usuarios (¡o incluso tú!) pueden pasar a tus funciones o scripts eliminará código innecesario dentro de tu función. Por ejemplo, digamos que pasas el valor 3 a tu función Instalar-Software
, sabiendo que la versión 3 es una versión existente.
Tu función asume que cada usuario sabe qué versiones existen, por lo que no tiene en cuenta qué sucede cuando intentas especificar la versión 4. En ese caso, la función no podrá encontrar la carpeta adecuada porque no existe.
Vida Sin Validación de Parámetros
Observa el ejemplo a continuación cuando usas la cadena $Version
en una ruta de archivo. Si alguien pasa un valor que no completa un nombre de carpeta existente (por ejemplo, SoftwareV3 o SoftwareV4), el código fallará.

Puedes escribir código de manejo de errores para abordar este problema, o puedes prevenir el problema exigiendo que el usuario pase solo una versión existente del software. Para limitar la entrada del usuario, agrega validación de parámetros.
Añadiendo Validación de Parámetros
Existen varios tipos de validación de parámetros, pero con respecto a tu función Install-Software
, el atributo [ValidateSet
](https://adamtheautomator.com/powershell-validateset/) funciona mejor. El atributo de validación ValidateSet
te permite especificar una lista de valores permitidos para el parámetro. Si solo estás considerando la cadena 1
o 2
, asegúrate de que el usuario pueda especificar solo estos valores; de lo contrario, la función fallará inmediatamente y notificará al usuario sobre el motivo.
Agrega atributos de validación de parámetros dentro del bloque param
, justo debajo del bloque original de Parameter
como se muestra a continuación.
Al agregar un conjunto de elementos (`1` y `2`) dentro de los paréntesis finales del atributo `ValidateSet`, esto le indica a PowerShell que los únicos valores válidos para `Version` son `1` o `2`. Si un usuario intenta pasar algo que no esté en el conjunto, recibirá un mensaje de error como se muestra a continuación notificándoles que solo tienen un número específico de opciones disponibles.

El atributo `ValidateSet` es un atributo de validación común, pero existen otros. Para obtener un desglose completo de todas las formas en que se pueden restringir los valores de los parámetros, consulte la documentación de Microsoft.
Aceptando Entrada de Canalización
Hasta ahora, has creado una función con un parámetro que solo se puede pasar usando la sintaxis típica `-NombreDelParámetro
Relacionado: Aceptación de Entrada de Canalización en el Artículo de Parámetros de PowerShell ATA
Primero, añade otro parámetro a tu código que especifique la computadora en la que deseas instalar el software. Además, agrega ese parámetro a tu referencia de Write-Host
para simular la instalación.
Una vez que hayas agregado el parámetro ComputerName
a la función, ahora puedes iterar sobre una lista de nombres de computadoras y pasar los valores del nombre de la computadora y la versión a la función Install-Software
, como se muestra a continuación.
En lugar de hacer todo eso, deberías aprender a usar el pipeline en su lugar.
Haciendo la Función Compatible con el Pipeline
Desafortunadamente, no puedes aprovechar el pipeline de PowerShell con una función simple construida anteriormente. Debes decidir qué tipo de entrada de pipeline quieres que la función acepte e implementarlo.
A PowerShell function uses two kinds of pipeline input: ByValue
(entire object) and ByPropertyName
(a single object property). Here, because the $computers
array contains only strings, you’ll pass those strings via ByValue
.
Para agregar soporte para el pipeline, agrega un atributo de parámetro al parámetro que deseas utilizando una de dos palabras clave: ValueFromPipeline
o ValueFromPipelineByPropertyName
, como se muestra a continuación.
Una vez que hayas cargado la función actualizada Install-Software
, llámala de la siguiente manera:
Ejecuta el script nuevamente y deberías obtener algo como esto:
Observa que Install-Software
se ejecuta solo para la última cadena en el array. Verás cómo solucionar esto en la siguiente sección.
Añadiendo un Bloque de Proceso
Para indicarle a PowerShell que ejecute esta función para cada objeto que llegue, debes incluir un bloque de proceso. Dentro del bloque de proceso, coloca el código que deseas ejecutar cada vez que la función reciba entrada del canal de procesamiento. Agrega un bloque de proceso a tu script como se muestra a continuación.
Ahora llama a la función nuevamente como lo hiciste antes. La función Install-Software
ahora devolverá tres líneas (una para cada objeto).
El bloque de proceso contiene el código principal que deseas ejecutar. También puedes usar bloques begin
y end
para código que se ejecutará al principio y al final de la llamada a la función. Puedes aprender más sobre los bloques begin
, process
y end
a través de la documentación de Microsoft.
Siguientes Pasos
Las funciones te permiten compartimentar el código en bloques de construcción discretos. No solo te ayudan a dividir tu trabajo en partes más pequeñas y manejables, sino que también te obligan a escribir código legible y probable.
I now challenge you to look through some old scripts and see where you can add a PowerShell function. Look for patterns in code. Build a function from those patterns. Notice where you’re copying/pasting code snippets and turn those into PowerShell functions!