Compartir a través de


Acerca de Funciones

Descripción breve

Describe cómo crear y usar funciones en PowerShell.

Descripción larga

Una función es una lista de instrucciones de PowerShell que tiene un nombre que se asigna. Al ejecutar una función, escriba el nombre de la función.

PowerShell define dos tipos de funciones:

  • Una función es un bloque de código al que se puede llamar por nombre. Puede tomar la entrada y devolver la salida. Las funciones se definen mediante la function palabra clave .
  • Un filtro es un tipo de función diseñada para procesar datos de la canalización. Los filtros se definen mediante la filter palabra clave .

Puede agrupar las instrucciones de una función en uno de los cuatro bloques de script predefinidos diferentes. Estos bloques de script se denominan mediante las palabras clave begin, process, endy clean. Si no usa estas palabras clave, PowerShell coloca las instrucciones en el bloque de código adecuado.

Functions también puede actuar como cmdlets. Puede crear una función que funcione igual que un cmdlet sin usar C# la programación. Para obtener más información, consulte about_Functions_Advanced.

Importante

Dentro de los archivos de script y los módulos basados en scripts, se deben definir funciones para poder llamar a ellas.

Sintaxis de la función

Las funciones se definen mediante la sintaxis siguiente:

function [<scope:>]<name> {
  param([type]$Parameter1 [,[type]$Parameter2])
  dynamicparam {<statement list>}
  begin {<statement list>}
  process {<statement list>}
  end {<statement list>}
  clean {<statement list>}
}

Una función incluye los siguientes elementos:

  • Palabra function clave
  • Un ámbito (opcional)
  • Un nombre que seleccione.
  • Cualquier número de parámetros con nombre (opcional), incluidos los parámetros dinámicos
  • Una o varias instrucciones de PowerShell entre llaves {}

Si no usa una de las palabras clave (, , , ) en una begin definición, PowerShell coloca las instrucciones en el process bloque . endcleanfunctionend

Para obtener más información sobre la palabra clave y los dynamicparam parámetros dinámicos en las funciones, consulte about_Functions_Advanced_Parameters.

Una función puede ser tan simple como:

function Get-PowerShellProcess { Get-Process pwsh }

Una vez definida una función, puede usarla como los cmdlets integrados. Por ejemplo, para llamar a la función recién definida Get-PowerShellProcess :

Get-PowerShellProcess
 NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
    110    78.72     172.39      10.62   10936   1 pwsh

Una función también puede ser tan compleja como un cmdlet.

Las funciones pueden devolver valores que se pueden mostrar, asignar a variables o pasarse a otras funciones o cmdlets. Puede usar la palabra clave para devolver la return salida. La return palabra clave no afecta ni suprime otra salida devuelta de la función. Sin embargo, la return palabra clave sale de la función en esa línea. Para obtener más información, consulte about_Return.

Sintaxis de filtro

La intención de la filter función es proporcionar una manera abreviada de definir una función que se ejecuta en cada objeto de la canalización.

La sintaxis de un filtro es la siguiente:

filter [<scope:>]<name> {<statement list>}

Para simplificar la sintaxis de filter las funciones, omita la palabra clave de bloque de script (begin, process, end, clean). PowerShell coloca las instrucciones en el process bloque . Puede usar cualquiera de los demás bloques de una función de filtro, pero la intención era proporcionar una manera abreviada de definir una función que tiene el único propósito de procesar cada objeto de la canalización.

El siguiente filtro toma entradas de registro de la canalización y, a continuación, muestra toda la entrada o solo la parte del mensaje de la entrada:

filter Get-EventMessage ([switch]$MessageOnly) {
  if ($MessageOnly) { Out-Host -InputObject $_.Message }
  else { $_ }
}

Se puede usar del modo indicado a continuación:

Get-WinEvent -LogName System -MaxEvents 100 | Get-EventMessage -MessageOnly

Métodos de procesamiento de entrada

Los métodos descritos en esta sección se conocen como métodos de procesamiento de entrada. En el caso de las funciones, estos tres métodos denominados mediante los beginbloques , processy end de la función . PowerShell 7.3 agrega un clean método de proceso de bloque.

No es necesario usar ninguno de estos bloques en las funciones. Si no usa un bloque con nombre, PowerShell coloca el código en el end bloque de la función. Sin embargo, si usa cualquiera de estos bloques con nombre o define un dynamicparam bloque, debe colocar todo el código en un bloque con nombre.

En el ejemplo siguiente se muestra el esquema de una función que contiene un bloque para el preprocesamiento único, un begin bloque de datos de bloque de la canalización y un process bloque para el procesamiento posterior de un end solo uso.

Function Test-ScriptCmdlet {
    [CmdletBinding(SupportsShouldProcess=$true)]
    param ($Parameter1)
    begin{}
    process{}
    end{}
}

begin

Este bloque se usa para proporcionar preprocesamiento opcional de un solo uso para la función. El tiempo de ejecución de PowerShell usa el código de este bloque una vez para cada instancia de la función de la canalización.

process

Este bloque se usa para proporcionar procesamiento de registros por registro para la función. Puede usar un process bloque sin definir los demás bloques. El número de ejecuciones de process bloques depende de cómo use la función y de qué entrada recibe la función.

La variable $_ automática o $PSItem contiene el objeto actual de la canalización para su uso en el process bloque . La $input variable automática contiene un enumerador que solo está disponible para funciones y bloques de script. Para obtener más información, vea about_Automatic_Variables.

  • Si la función se invoca sin entrada de canalización, PowerShell ejecuta el process bloque solo una vez.
  • Dentro de una canalización, el process bloque se ejecuta una vez para cada objeto de entrada que alcanza la función.
  • Si la entrada de canalización que llega a la función está vacía, el process bloque no se ejecuta.
    • Los beginbloques , endy clean se siguen ejecutando.

Importante

Si un parámetro de función acepta la entrada de canalización y no se define un bloque, se produce un process error en el procesamiento de registros por registro. En este caso, la función solo se ejecuta una vez, independientemente de la entrada.

end

Use este bloque para proporcionar el procesamiento posterior opcional de una sola vez para la función.

clean

El clean bloque se agregó en PowerShell 7.3.

El bloque clean es una manera cómoda para que los usuarios limpien los recursos que abarcan los bloques begin, process y end. Es semánticamente similar a un bloque finally que cubre todos los demás bloques con nombre de una función de script o un cmdlet de script. La limpieza de recursos se aplica en los escenarios siguientes:

  1. cuando finaliza la ejecución de la canalización sin finalizar el error
  2. cuando se interrumpe la ejecución de la canalización debido a un error de terminación
  3. cuando se trunca la canalización, por ejemplo: Select-Object -First
  4. cuando la canalización se detiene mediante Ctrl+c o StopProcessing()

El bloque limpio descarta cualquier salida escrita en el flujo Correcto .

Precaución

Agregar el bloque clean es un cambio importante. Dado que clean se analiza como una palabra clave, impide que los usuarios llamen directamente a un comando denominado clean como la primera instrucción de un bloque de script. Sin embargo, es probable que no sea un problema. Todavía puede invocar el comando mediante el operador de llamada (& clean).

Funciones sencillas

Las funciones no tienen que ser complicadas de ser útiles. Las funciones más sencillas tienen el siguiente formato:

function <function-name> { statements }

Por ejemplo, la siguiente función inicia PowerShell con la opción Ejecutar como administrador .

function Start-PSAdmin { Start-Process PowerShell -Verb RunAs }

Para usar la función , escriba: Start-PSAdmin

Para agregar instrucciones a la función, escriba cada instrucción en una línea independiente o use un punto y coma (;) para separar las instrucciones.

Por ejemplo, la siguiente función busca todos los .jpg archivos de los directorios del usuario actual que se cambiaron después de la fecha de inicio.

function Get-NewPicture {
  $start = Get-Date -Month 1 -Day 1 -Year 2010
  $allPics = Get-ChildItem -Path $Env:USERPROFILE\*.jpg -Recurse
  $allPics | Where-Object {$_.LastWriteTime -gt $Start}
}

Puede crear un cuadro de herramientas de funciones pequeñas útiles. Agregue estas funciones al perfil de PowerShell, como se describe en about_Profiles y versiones posteriores de este artículo.

Nombres de función

Puede asignar cualquier nombre a una función. Sin embargo, para las funciones que comparte con otros usuarios, debe seguir las reglas de nomenclatura estándar de PowerShell.

  • Los nombres deben estar formados por un par verbo-sustantivo donde el verbo identifica la acción que realiza la función y el nombre identifica el elemento en el que el cmdlet realiza la acción.
  • Los nombres deben usar los verbos aprobados para todos los comandos de PowerShell. El uso de verbos aprobados crea coherencia para los usuarios.

Para obtener más información sobre los verbos estándar de PowerShell, consulte Verbos aprobados.

Funciones con parámetros

Puede usar parámetros con funciones, incluidos los parámetros con nombre, los parámetros posicionales, los parámetros switch y los parámetros dinámicos. Para obtener más información sobre los parámetros dinámicos en las funciones, consulte about_Functions_Advanced_Parameters.

Parámetros con nombre

Puede definir cualquier número de parámetros con nombre. Puede incluir un valor predeterminado para los parámetros con nombre, como se describe más adelante en este artículo.

Puede definir parámetros dentro de las llaves mediante la param palabra clave , como se muestra en la sintaxis de ejemplo siguiente:

function <name> {
  param ([type]$Parameter1 [,[type]$Parameter2])
  <statement list>
}

También puede definir parámetros fuera de las llaves sin la param palabra clave , como se muestra en la sintaxis de ejemplo siguiente:

function <name> [([type]$Parameter1[,[type]$Parameter2])] {
  <statement list>
}

Por ejemplo, la función siguiente usa la sintaxis alternativa para definir dos parámetros:

function Add-Numbers([int]$One, [int]$Two) {
    $One + $Two
}

Aunque se prefiere el primer método, no hay ninguna diferencia entre estos dos métodos.

Al ejecutar la función, el valor proporcionado para un parámetro se asigna a una variable que contiene el nombre del parámetro. El valor de esa variable se puede usar en la función .

El ejemplo siguiente es una función denominada Get-SmallFiles. Esta función tiene un $Size parámetro . La función muestra todos los archivos que son más pequeños que el valor del $Size parámetro y excluye los directorios:

function Get-SmallFiles {
  param ($Size)
  Get-ChildItem $HOME | Where-Object {
    $_.Length -lt $Size -and !$_.PSIsContainer
  }
}

En la función , puede usar la $Size variable , que es el nombre definido para el parámetro .

Para usar esta función, escriba el siguiente comando:

Get-SmallFiles -Size 50

También puede escribir un valor para un parámetro con nombre sin el nombre del parámetro. Por ejemplo, el siguiente comando proporciona el mismo resultado que un comando que asigna un nombre al parámetro Size :

Get-SmallFiles 50

Para definir un valor predeterminado para un parámetro, escriba un signo igual y el valor después del nombre del parámetro, como se muestra en la siguiente variación del Get-SmallFiles ejemplo:

function Get-SmallFiles ($Size = 100) {
  Get-ChildItem $HOME | Where-Object {
    $_.Length -lt $Size -and !$_.PSIsContainer
  }
}

Si escribe Get-SmallFiles sin un valor, la función asigna 100 a $size. Si proporciona un valor, la función usa ese valor.

Opcionalmente, puede proporcionar una breve cadena de ayuda que describa el valor predeterminado del parámetro agregando el atributo PSDefaultValue a la descripción del parámetro y especificando la propiedad Help de PSDefaultValue. Para proporcionar una cadena de ayuda que describa el valor predeterminado (100) del parámetro Size en la Get-SmallFiles función, agregue el atributo PSDefaultValue como se muestra en el ejemplo siguiente.

function Get-SmallFiles {
  param (
      [PSDefaultValue(Help = '100')]
      $Size = 100
  )
  Get-ChildItem $HOME | Where-Object {
    $_.Length -lt $Size -and !$_.PSIsContainer
  }
}

Para obtener más información sobre la clase de atributo PSDefaultValue , vea Miembros de atributo PSDefaultValue.

Parámetros posicionales

Un parámetro posicional es un parámetro sin un nombre de parámetro. PowerShell usa el orden de valor de parámetro para asociar cada valor de parámetro a un parámetro de la función .

Cuando se usan parámetros posicionales, escriba uno o varios valores después del nombre de la función. Los valores de parámetro posicional se asignan a la $args variable de matriz. El valor que sigue al nombre de la función se asigna a la primera posición de la $args matriz, $args[0].

La siguiente Get-Extension función agrega la .txt extensión de nombre de archivo a un nombre de archivo que proporcione:

function Get-Extension {
  $name = $args[0] + ".txt"
  $name
}
Get-Extension myTextFile
myTextFile.txt

Parámetros de conmutación

Un modificador es un parámetro que no requiere un valor. En su lugar, escriba el nombre de la función seguido del nombre del parámetro switch.

Para definir un parámetro switch, especifique el tipo [switch] antes del nombre del parámetro, como se muestra en el ejemplo siguiente:

function Switch-Item {
  param ([switch]$On)
  if ($On) { "Switch on" }
  else { "Switch off" }
}

Al escribir el parámetro switch después del On nombre de la función, la función muestra Switch on. Sin el parámetro switch, muestra Switch off.

Switch-Item -On
Switch on
Switch-Item
Switch off

También puede asignar un valor booleano a un modificador al ejecutar la función, como se muestra en el ejemplo siguiente:

Switch-Item -On:$true
Switch on
Switch-Item -On:$false
Switch off

Uso de la expansión para pasar valores de parámetro

Puede usar la expansión para representar los parámetros de un comando. Esta característica se presenta en Windows PowerShell 3.0.

Use esta técnica en funciones que llaman a comandos en la sesión. No es necesario declarar ni enumerar los parámetros de comando ni cambiar la función cuando cambien los parámetros de comando.

La siguiente función de ejemplo llama al Get-Command cmdlet . El comando usa @args para representar los parámetros de Get-Command.

function Get-MyCommand { Get-Command @args }

Puede usar todos los parámetros de Get-Command al llamar a la Get-MyCommand función . Los parámetros y los valores de parámetro se pasan al comando mediante @args.

Get-MyCommand -Name Get-ChildItem
CommandType     Name                ModuleName
-----------     ----                ----------
Cmdlet          Get-ChildItem       Microsoft.PowerShell.Management

La @args característica usa el $args parámetro automático, que representa los parámetros y valores de cmdlet no declarados de los argumentos restantes.

Para obtener más información, consulte about_Splatting.

Canalización de objetos a funciones

Cualquier función puede tomar la entrada de la canalización. Puede controlar cómo una función procesa la entrada desde la canalización mediante beginpalabras clave , process, endy clean . La siguiente sintaxis de ejemplo muestra estas palabras clave:

La lista de process instrucciones se ejecuta una vez para cada objeto de la canalización. Mientras se ejecuta el process bloque, cada objeto de canalización se asigna a la $_ variable automática, un objeto de canalización cada vez.

La función siguiente usa la process palabra clave . La función muestra los valores de la canalización:

function Get-Pipeline
{
  process {"The value is: $_"}
}

1, 2, 4 | Get-Pipeline
The value is: 1
The value is: 2
The value is: 4

Si desea una función que pueda tomar la entrada de canalización o la entrada de un parámetro, el process bloque debe controlar ambos casos. Por ejemplo:

function Get-SumOfNumbers {
    param (
        [int[]]$Numbers
    )

    begin { $retValue = 0 }

    process {
        if ($null -ne $Numbers) {
           foreach ($n in $Numbers) {
               $retValue += $n
           }
        } else {
           $retValue += $_
        }
    }

    end { $retValue }
}

PS> 1, 2, 3, 4 | Get-SumOfNumbers
10
PS> Get-SumOfNumbers 1, 2, 3, 4
10

Cuando se usa una función en una canalización, los objetos canalizado a la función se asignan a la $input variable automática. La función ejecuta instrucciones con el bloque de begin script antes de que los objetos provengan de la canalización. La función ejecuta instrucciones con el bloque de end script cuando no hay más objetos en la canalización.

En el ejemplo siguiente se muestra la $input variable automática usada en los begin bloques de script y end .

function Get-PipelineBeginEnd {
    begin   { "Begin: The input is $input" }
    end     { "End:   The input is $input" }
}

Al ejecutar la función con entrada de canalización, se muestran los siguientes resultados:

1, 2, 4 | Get-PipelineBeginEnd
Begin: The input is
End:   The input is 1 2 4

Cuando se ejecuta la begin instrucción , la función no tiene la entrada de la canalización. La end instrucción se ejecuta después de que la función tenga los valores .

Si la función tiene una process palabra clave , cada objeto de $input se quita de $input y se asigna a $_. En el ejemplo siguiente se incluye una process lista de instrucciones:

function Get-PipelineInput
{
    process {"Processing:  $_ " }
    end     {"End:   The input is: $input" }
}

En este ejemplo, cada objeto canalización a la función se envía a la lista de process instrucciones. Las process instrucciones se ejecutan en cada objeto, un objeto cada vez. La $input variable automática está vacía cuando la función alcanza la end palabra clave .

1, 2, 4 | Get-PipelineInput
Processing:  1
Processing:  2
Processing:  4
End:   The input is:

Para obtener más información, consulte Using Enumerators (Usar enumeradores).

PowerShell 7.3 agregó el clean bloque . El bloque clean es una manera cómoda para que los usuarios limpien los recursos creados y usados en los bloques begin, process y end. Es semánticamente similar a un bloque finally que cubre todos los demás bloques con nombre de una función de script o un cmdlet de script. La limpieza de recursos se aplica en los escenarios siguientes:

  1. cuando la ejecución de la canalización finaliza normalmente sin error de terminación
  2. cuando se interrumpe la ejecución de la canalización debido a un error de terminación
  3. cuando se trunca la canalización, por ejemplo: Select-Object -First
  4. cuando la canalización se detiene mediante Ctrl+C o StopProcessing()

Precaución

Agregar el bloque clean es un cambio importante. Dado que clean se analiza como una palabra clave, impide que los usuarios llamen directamente a un comando denominado clean como la primera instrucción de un bloque de script. Sin embargo, es probable que no sea un problema. El comando todavía se puede invocar mediante el operador de llamada (& clean).

Ámbito de la función

Existe una función en el ámbito en el que se crea.

Si una función forma parte de un script, la función está disponible para las instrucciones de ese script. De forma predeterminada, una función de un script no está disponible fuera de ese script.

Puede especificar el ámbito de una función. Por ejemplo, la función se agrega al ámbito global en el ejemplo siguiente:

function Global:Get-DependentSvs {
  Get-Service | Where-Object {$_.DependentServices}
}

Cuando una función está en el ámbito global, puede usar la función en scripts, en funciones y en la línea de comandos.

Las funciones crean un nuevo ámbito. Los elementos creados en una función, como variables, solo existen en el ámbito de la función.

Para obtener más información, consulte about_Scopes.

Búsqueda y administración de funciones mediante la Function: unidad

Todas las funciones y filtros de PowerShell se almacenan automáticamente en la Function: unidad. El proveedor de funciones de PowerShell expone esta unidad.

Al hacer referencia a la Function: unidad, escriba dos puntos después de Function, como haría al hacer referencia a la C unidad o D de un equipo.

El siguiente comando muestra todas las funciones de la sesión actual de PowerShell:

Get-ChildItem Function:

Los comandos de la función se almacenan como un bloque de script en la propiedad de definición de la función. Por ejemplo, para mostrar los comandos de la función de Ayuda que viene con PowerShell, escriba:

(Get-ChildItem Function:help).Definition

También puede usar la sintaxis siguiente.

$Function:help

Para obtener más información, consulte about_Function_Provider.

Reutilización de funciones en nuevas sesiones

Al escribir una función en el símbolo del sistema de PowerShell, la función forma parte de la sesión actual. La función está disponible hasta que finaliza la sesión.

Para usar la función en todas las sesiones de PowerShell, agregue la función al perfil de PowerShell. Para obtener más información sobre los perfiles, consulte about_Profiles.

También puede guardar la función en un archivo de script de PowerShell. Escriba la función en un archivo de texto y guarde el archivo con la extensión de nombre de .ps1 archivo.

Creación de ayuda para funciones

El Get-Help cmdlet obtiene ayuda para funciones, cmdlets, proveedores y scripts. Para obtener ayuda para una función, escriba Get-Help seguido del nombre de la función.

Por ejemplo, para obtener ayuda para la Get-MyDisks función, escriba:

Get-Help Get-MyDisks

Puede escribir ayuda para una función mediante cualquiera de los dos métodos siguientes:

  • Ayuda basada en comentarios para funciones

    Cree ayuda con palabras clave especiales en los comentarios. Para crear ayuda basada en comentarios para una función, los comentarios deben colocarse al principio, al final o dentro del cuerpo de la función. Para obtener más información sobre la ayuda basada en comentarios, consulte about_Comment_Based_Help.

  • Ayuda basada en XML para funciones

    Se requiere ayuda basada en XML si necesita localizar contenido de ayuda en varios idiomas. Para asociar la función con el archivo de ayuda basado en XML, use la .EXTERNALHELP palabra clave de ayuda basada en comentarios. Sin esta palabra clave, Get-Help no puede encontrar el archivo de ayuda de la función y solo devuelve la ayuda generada automáticamente.

    Para obtener más información sobre la .EXTERNALHELP palabra clave , consulte about_Comment_Based_Help. Para obtener más información sobre la ayuda basada en XML, vea Cómo escribir ayuda de cmdlets.

Consulte también