Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Nota editorial
Importante
La Especificación del lenguaje de Windows PowerShell, versión 3.0 se publicó en diciembre de 2012 y está basada en Windows PowerShell 3.0. Esta especificación no refleja el estado actual de PowerShell. No hay ningún plan para actualizar esta documentación para reflejar el estado actual. Esta documentación se presenta aquí para obtener referencia histórica.
El documento de especificación está disponible como un documento de Microsoft Word del Centro de descarga de Microsoft en: https://www.microsoft.com/download/details.aspx?id=36389 Ese documento de Word se ha convertido para su presentación aquí en Microsoft Learn. Durante la conversión, se han realizado algunos cambios editoriales para dar cabida al formato de la plataforma Docs. Se han corregido algunos errores tipográficos y menores.
8.1 Bloques de declaraciones y listas
Sintaxis:
Sugerencia
La notación ~opt~
en las definiciones de sintaxis indica que la entidad léxica es opcional en la sintaxis.
statement-block:
new-lines~opt~ { statement-list~opt~ new-lines~opt~ }
statement-list:
statement
statement-list statement
statement:
if-statement
label~opt~ labeled-statement
function-statement
flow-control-statement statement-terminator
trap-statement
try-statement
data-statement
inlinescript-statement
parallel-statement
sequence-statement
pipeline statement-terminator
statement-terminator:
;
new-line-character
Descripción:
Una instrucción especifica algún tipo de acción que se va a realizar. A menos que se indique lo contrario dentro de esta cláusula, las instrucciones se ejecutan en orden léxico.
Un elemento statement-block permite agrupar un conjunto de instrucciones en una sola unidad sintáctica.
8.1.1 Instrucciones etiquetadas
Sintaxis:
labeled-statement:
switch-statement
foreach-statement
for-statement
while-statement
do-statement
Descripción:
Una instrucción de iteración (§8.4) o una instrucción switch (§8.6), opcionalmente, puede ir precedida de inmediato por una etiqueta de instrucción, label. Una etiqueta de instrucción se usa como destino opcional de una instrucción break (§8.5.1) o continue (§8.5.2). Sin embargo, una etiqueta no modifica el flujo de control.
No se permite que haya un espacio en blanco entre los dos puntos (:
) y el token que lo sigue.
Ejemplos:
:go_here while ($j -le 100) {
# ...
}
:labelA
for ($i = 1; $i -le 5; ++$i) {
:labelB
for ($j = 1; $j -le 3; ++$j) {
:labelC
for ($k = 1; $k -le 2; ++$k) {
# ...
}
}
}
8.1.2 Declaración de valores
El valor de una instrucción es el conjunto acumulativo de valores que escribe en la canalización. Si la instrucción escribe un único valor escalar, ese es el valor de la instrucción. Si la instrucción escribe varios valores, el valor de la instrucción es ese conjunto de valores almacenados en elementos de una matriz 1 dimensional sin restricciones, en el orden en que se escribieron. Tenga en cuenta el ejemplo siguiente:
$v = for ($i = 10; $i -le 5; ++$i) { }
No hay ninguna iteración del bucle y no se escribe nada en la canalización. El valor de la instrucción es $null
.
$v = for ($i = 1; $i -le 5; ++$i) { }
Aunque el bucle itera cinco veces, no se escribe nada en la canalización. El valor de la instrucción es $null.
$v = for ($i = 1; $i -le 5; ++$i) { $i }
El bucle itera cinco veces cada vez que se escribe en la canalización el valor int
$i
. El valor de la instrucción es object[]
de longitud 5.
$v = for ($i = 1; $i -le 5; ) { ++$i }
Aunque el bucle itera cinco veces, no se escribe nada en la canalización. El valor de la instrucción es $null
.
$v = for ($i = 1; $i -le 5; ) { (++$i) }
El bucle itera cinco veces con cada valor que se escribe en la canalización. El valor de la instrucción es object[]
de longitud 5.
$i = 1; $v = while ($i++ -lt 2) { $i }
El bucle itera una vez. El valor de la instrucción es el elemento int
con valor 2.
Estos son algunos otros ejemplos:
# if $count is not currently defined then define it with int value 10
$count = if ($count -eq $null) { 10 } else { $count }
$i = 1
$v = while ($i -le 5) {
$i # $i is written to the pipeline
if ($i -band 1) {
"odd" # conditionally written to the pipeline
}
++$i # not written to the pipeline
}
# $v is object[], Length 8, value 1,"odd",2,3,"odd",4,5,"odd"
8.2 Instrucciones de canalización
Sintaxis:
pipeline:
assignment-expression
expression redirections~opt~ pipeline-tail~opt~
command verbatim-command-argument~opt~ pipeline-tail~opt~
assignment-expression:
expression assignment-operator statement
pipeline-tail:
| new-lines~opt~ command
| new-lines~opt~ command pipeline-tail
command:
command-name command-elements~opt~
command-invocation-operator command-module~opt~ command-name-expr command-elements~opt~
command-invocation-operator: one of
& .
command-module:
primary-expression
command-name:
generic-token
generic-token-with-subexpr
generic-token-with-subexpr:
No whitespace is allowed between ) and command-name.
generic-token-with-subexpr-start statement-list~opt~ )
command-namecommand-name-expr:
command-name
primary-expressioncommand-elements:
command-element
command-elements command-element
command-element:
command-parameter
command-argument
redirection
command-argument:
command-name-expr
verbatim-command-argument:
--% verbatim-command-argument-chars
Descripción:
redirections se analiza en §7.12; assignment-expression se analiza en §7.11 y el punto command-invocation-operator (.
) se analiza en §3.5.5. Para obtener una explicación de la asignación de argumentos a parámetros en las invocaciones de comandos, consulte §8.14.
El primer comando en una canalización es una expresión o una invocación de comando. Normalmente, una invocación de comandos comienza con un elemento command-name, que suele ser un identificador básico. command-elements representa la lista de argumentos del comando. Una nueva línea o un punto y coma sin escapes termina una canalización.
Una invocación de comando consta del nombre del comando seguido de cero o más argumentos. Las reglas que rigen los argumentos son las siguientes:
Un argumento que no es una expresión, pero que contiene texto arbitrario sin espacios en blanco sin escapes, se trata como si estuviera entre comillas dobles. Se conserva la escritura bicameral.
La sustitución de variables y la expansión de subexpresiones ((§2.3.5.2) tiene lugar dentro de expandable-string-literals y expandable-here-string-literals.
El texto entre comillas permite incluir espacios en blanco iniciales, finales e incrustados en el valor del argumento. [Nota: la presencia de espacios en blanco en un argumento entrecomillado no convierte un único argumento en varios argumentos. nota final]
Colocar paréntesis alrededor de un argumento provoca que esa expresión se evalúe, y el resultado se pasa en lugar del texto de la expresión original.
Para pasar un argumento similar a un parámetro switch (§2.3.4), pero no está pensado como tal, incluya ese argumento entre comillas.
Al especificar un argumento que coincide con un parámetro que tiene la restricción de tipo
[switch]
(§8.10.5), la presencia del nombre del argumento por sí mismo hace que ese parámetro se establezca en$true
. Sin embargo, el valor del parámetro se puede establecer explícitamente anexando un sufijo al argumento . Por ejemplo, dado un parámetro restringido de tipo p, un argumento de-p:$true
establece p en True, mientras que-p:$false
establece p en False.Un argumento de
--
indica que todos los argumentos siguientes deben pasarse en su forma real como si se colocaran comillas dobles alrededor de ellos.Un argumento de
--%
indica que todos los argumentos siguientes deben ser sometidos a un análisis y procesamiento mínimos. Este argumento se denomina parámetro textual. Los argumentos después del parámetro textual no son expresiones de PowerShell aunque sean expresiones de PowerShell válidas sintácticamente.
Si el tipo de comando es Application, el parámetro --%
no se pasa al comando. Los argumentos después de --%
tienen expandidas las variables de entorno (cadenas rodeadas de %
). Por ejemplo:
echoargs.exe --% "%path%" # %path% is replaced with the value $env:path
El orden de evaluación de argumentos no se especifica.
Para obtener información sobre el enlace de parámetros, consulte §8.14. Para obtener información sobre la búsqueda de nombres, consulte §3.8.
Una vez completado el procesamiento de argumentos, se invoca el comando . Si el comando invocado finaliza normalmente (§8.5.4), el control vuelve al punto del script o función inmediatamente después de la invocación del comando. Para obtener una descripción del comportamiento sobre la finalización anómala, consulte break
(§8.5.1), continue
(§8.5.2), throw
(§8.5.3), exit
(§8.5.5), try
(§8.7) y trap
(§8.8).
Normalmente, se invoca un comando mediante su nombre seguido de cualquier argumento. Sin embargo, se puede usar el operador de invocación de comandos, &, . Si el nombre del comando contiene espacios en blanco sin escapes, se debe poner entre comillas e invocar con este operador. Como un bloque de script no tiene ningún nombre, también debe invocarse con este operador. Por ejemplo, las siguientes invocaciones de una llamada de comando Get-Factorial
son equivalentes:
Get-Factorial 5
& Get-Factorial 5
& "Get-Factorial" 5
Se permiten llamadas de función recursivas directas e indirectas. Por ejemplo
function Get-Power([int]$x, [int]$y) {
if ($y -gt 0) { return $x * (Get-Power $x (--$y)) }
else { return 1 }
}
Ejemplos:
New-Object 'int[,]' 3,2
New-Object -ArgumentList 3,2 -TypeName 'int[,]'
dir e:\PowerShell\Scripts\*statement*.ps1 | Foreach-Object {$_.Length}
dir e:\PowerShell\Scripts\*.ps1 | Select-String -List "catch" | Format-Table path,linenumber -AutoSize
8.3 La instrucción if
Sintaxis:
if-statement:
if new-lines~opt~ ( new-lines~opt~ pipeline new-lines~opt~ ) statement-block
elseif-clauses~opt~ else-clause~opt~
elseif-clauses:
elseif-clause
elseif-clauses elseif-clause
elseif-clause:
new-lines~opt~ elseif new-lines~opt~ ( new-lines~opt~ pipeline new-lines~opt~ ) statement-block
else-clause:
new-lines~opt~ else statement-block
Descripción:
Las expresiones de control pipeline deben ser de tipo booleano o poder convertirse de forma implícita a ese tipo. La cláusula else-clause es opcional. Puede haber cero o más cláusulas elseif-clause.
Si se comprueba que la expresión pipeline es True, su statement-block se ejecuta y finaliza la ejecución de la instrucción. De lo contrario, si hay una cláusula elseif-clause presente, si se comprueba que su expresión pipeline es True, su statement-block se ejecuta y finaliza la ejecución de la instrucción. De lo contrario, si hay una cláusula else-clause presente, su statement-block se ejecuta.
Ejemplos:
$grade = 92
if ($grade -ge 90) { "Grade A" }
elseif ($grade -ge 80) { "Grade B" }
elseif ($grade -ge 70) { "Grade C" }
elseif ($grade -ge 60) { "Grade D" }
else { "Grade F" }
8.4 Instrucciones de iteración
8.4.1 La instrucción while
Sintaxis:
while-statement:
while new-lines~opt~ ( new-lines~opt~ while-condition new-lines~opt~ ) statement-block
while-condition:
new-lines~opt~ pipeline
Descripción:
La expresión de control while-condition debe tener el tipo bool o ser implícitamente convertible a ese tipo. El cuerpo del bucle, que consta de statement-block, se ejecuta repetidamente hasta que se comprueba que la expresión de control es False. La expresión de control se evalúa antes de cada ejecución del cuerpo del bucle.
Ejemplos:
$i = 1
while ($i -le 5) { # loop 5 times
"{0,1}`t{1,2}" -f $i, ($i*$i)
++$i
}
8.4.2 La instrucción do
Sintaxis:
do-statement:
do statement-block new-lines~opt~ while new-lines~opt~ ( while-condition new-lines~opt~ )
do statement-block new-lines~opt~ until new-lines~opt~ ( while-condition new-lines~opt~ )
while-condition:
new-lines~opt~ pipeline
Descripción:
La expresión de control while-condition debe ser de tipo booleano o poder convertirse de forma implícita a ese tipo. Cuando se usa while, el cuerpo del bucle, que incluye statement-block, se ejecuta repetidamente hasta que se comprueba que la expresión de control es True. Cuando se usa until, el cuerpo del bucle se ejecuta repetidamente hasta que se comprueba que la expresión de control es True. La expresión de control se evalúa después de cada ejecución del cuerpo del bucle.
Ejemplos:
$i = 1
do {
"{0,1}`t{1,2}" -f $i, ($i * $i)
}
while (++$i -le 5) # loop 5 times
$i = 1
do {
"{0,1}`t{1,2}" -f $i, ($i * $i)
}
until (++$i -gt 5) # loop 5 times
8.4.3 Instrucción for
Sintaxis:
for-statement:
for new-lines~opt~ (
new-lines~opt~ for-initializer~opt~ statement-terminator
new-lines~opt~ for-condition~opt~ statement-terminator
new-lines~opt~ for-iterator~opt~
new-lines~opt~ ) statement-block
for new-lines~opt~ (
new-lines~opt~ for-initializer~opt~ statement-terminator
new-lines~opt~ for-condition~opt~
new-lines~opt~ ) statement-block
for new-lines~opt~ (
new-lines~opt~ for-initializer~opt~
new-lines~opt~ ) statement-block
for-initializer:
pipeline
for-condition:
pipeline
for-iterator:
pipeline
Descripción:
La expresión de control for-condition debe tener el tipo bool o convertirse implícitamente en ese tipo. El cuerpo del bucle, que incluye statement-block, se ejecuta repetidamente hasta que se comprueba que la expresión de control es True. La expresión de control se evalúa antes de cada ejecución del cuerpo del bucle.
La expresión for-initializer se evalúa antes de la primera evaluación de la expresión de control. De la expresión for-initializer solo se evalúan sus efectos secundarios; cualquier valor que genera se descarta y no se escribe en la canalización.
La expresión for-iterator se evalúa después de cada ejecución del cuerpo del bucle. De la expresión for-iterator solo se evalúan sus efectos secundarios; cualquier valor que genera se descarta y no se escribe en la canalización.
Si se omite la expresión for-condition, la expresión de control comprueba True.
Ejemplos:
for ($i = 5; $i -ge 1; --$i) { # loop 5 times
"{0,1}`t{1,2}" -f $i, ($i * $i)
}
$i = 5
for (; $i -ge 1; ) { # equivalent behavior
"{0,1}`t{1,2}" -f $i, ($i * $i)
--$i
}
8.4.4 Instrucción foreach
Sintaxis:
foreach-statement:
foreach new-lines~opt~ foreach-parameter~opt~ new-lines~opt~
( new-lines~opt~ variable new-lines~opt~ *in* new-lines~opt~ pipeline
new-lines~opt~ ) statement-block
foreach-parameter:
-parallel
Descripción:
Se ejecuta el cuerpo del bucle, que incluye statement-block, para cada elemento designado por la instancia de variable en la colección designada por la canalización pipeline. El ámbito de variable no se limita a la instrucción foreach. Por lo tanto, conserva su valor final una vez que el cuerpo del bucle haya terminado de ejecutarse. Si la tubería designa un escalar (excluyendo el valor $null) en lugar de una colección, se trata ese escalar como una colección de un solo elemento. Si canalización designa el valor $null
, canalización se trata como una colección de cero elementos.
Si se especifica el parámetro foreach-parameter-parallel
, el comportamiento depende de la implementación.
El parámetro foreach-parameter‑parallel
solo se permite en un flujo de trabajo (§8.10.2).
Cada instrucción foreach tiene su propio enumerador, $foreach
(§2.3.2.2, §4.5.16), que solo existe mientras se ejecuta ese bucle.
Los objetos generados por la canalización se recopilan antes de que el bloque de instrucciones empiece a ejecutarse. Sin embargo, con el cmdlet ForEach-Object, el bloque de instrucciones se ejecuta en cada objeto a medida que se produce.
Ejemplos:
$a = 10, 53, 16, -43
foreach ($e in $a) {
...
}
$e # the int value -43
foreach ($e in -5..5) {
...
}
foreach ($t in [byte], [int], [long]) {
$t::MaxValue # get static property
}
foreach ($f in Get-ChildItem *.txt) {
...
}
$h1 = @{ FirstName = "James"; LastName = "Anderson"; IDNum = 123 }
foreach ($e in $h1.Keys) {
"Key is " + $e + ", Value is " + $h1[$e]
}
8.5 Instrucciones de control de flujo
Sintaxis:
flow-control-statement:
break label-expression~opt~
continue label-expression~opt~
throw pipeline~opt~
return pipeline~opt~
exit pipeline~opt~
label-expression:
simple-name
unary-expression
Descripción:
Una instrucción de control de flujo provoca una transferencia incondicional del control a alguna otra ubicación.
8.5.1 Instrucción break
Descripción:
Una instrucción break con un elemento label-expression se conoce como instrucción break con etiqueta. Una instrucción break sin un elemento label-expression se conoce como instrucción break sin etiqueta.
Fuera de una instrucción trap, una instrucción break sin etiqueta incluida directamente en una instrucción de iteración (§8.4) finaliza la ejecución de esa instrucción de iteración envolvente más pequeña. Una instrucción break sin etiqueta incluida directamente en una instrucción switch (§8.6) finaliza la coincidencia de patrones para la condición switch-condition del modificador actual. Consulte la sección (§8.8) para obtener más detalles sobre el uso de break desde dentro de una instrucción trap.
Una instrucción de iteración o una instrucción switch también puede ir precedida de forma inmediata por una etiqueta de instrucción (§8.1.1). Dicha etiqueta de instrucción se puede usar como destino de una instrucción break con etiqueta y, en ese caso, la instrucción finaliza la ejecución de la instrucción de iteración envolvente de destino.
No es necesario resolver una instrucción break con etiqueta en ningún ámbito local; la búsqueda de una etiqueta coincidente puede continuar en la pila de llamadas, incluso más allá de los límites de script y de llamadas a funciones. Si no se encuentra ninguna etiqueta coincidente, se finaliza la invocación del comando actual.
El nombre de la etiqueta designada por etiqueta-expresión no necesita tener un valor constante.
Si la expresión etiqueta es una expresión unaria , se convierte en una cadena.
Ejemplos:
$i = 1
while ($true) { # infinite loop
if ($i * $i -gt 100) {
break # break out of current while loop
}
++$i
}
$lab = "go_here"
:go_here
for ($i = 1; ; ++$i) {
if ($i * $i -gt 50) {
break $lab # use a string value as target
}
}
:labelA
for ($i = 1; $i -le 2; $i++) {
:labelB
for ($j = 1; $j -le 2; $j++) {
:labelC
for ($k = 1; $k -le 3; $k++) {
if (...) { break labelA }
}
}
}
8.5.2 Instrucción continue
Descripción:
Una instrucción continue
con un elemento label-expression se conoce como instrucción continue con etiqueta. Una instrucción continue sin un elemento label-expression se conoce como instrucción continue sin etiqueta.
El uso de continue
desde una instrucción trap se analiza en la sección §8.8.
Una instrucción continue
sin etiquetar dentro de un bucle finaliza la ejecución del bucle actual y transfiere el control al corchete de cierre de la instrucción de iteración envolvente más pequeña (§8.4). Una instrucción continue
sin etiqueta dentro de un modificador switch finaliza la ejecución de la iteración switch
actual y transfiere el control a la condición switch-condition del elemento switch
envolvente más pequeño (§8.6).
Una instrucción de iteración o una instrucción switch
(§8.6) puede ir precedida de forma inmediata por una etiqueta de instrucción (§8.1.1). Dicha etiqueta se puede usar como destino de una instrucción continue
con etiqueta incluida; en ese caso, la instrucción finaliza la ejecución del bucle o la iteración switch
actual y transfiere el control a la etiqueta de instrucción switch
o iteración envolvente de destino.
No es necesario resolver una instrucción continue
con etiqueta en ningún ámbito local; la búsqueda de una etiqueta coincidente puede aplicar continue
hasta la pila de llamadas, incluso más allá de los límites de script y de llamadas a funciones. Si no se encuentra ninguna etiqueta coincidente, se finaliza la invocación del comando actual.
El nombre de la etiqueta designada por etiqueta-expresión no necesita tener un valor constante.
Si label-expression es de tipo unary-expression, se convierte en una cadena.
Ejemplos:
$i = 1
while (...) {
...
if (...) {
continue # start next iteration of current loop
}
...
}
$lab = "go_here"
:go_here
for (...; ...; ...) {
if (...) {
continue $lab # start next iteration of labeled loop
}
}
:labelA
for ($i = 1; $i -le 2; $i++) {
:labelB
for ($j = 1; $j -le 2; $j++) {
:labelC
for ($k = 1; $k -le 3; $k++) {
if (...) { continue labelB }
}
}
}
8.5.3 Instrucción throw
Descripción:
Una excepción es una forma de controlar una condición de error de nivel de aplicación o del sistema. La instrucción throw genera una excepción. (Consulte §8.7 para obtener una explicación del control de excepciones).
Si la canalización pipeline se omite y la instrucción throw no está en una cláusula catch-clause, el comportamiento lo define la implementación. Si la canalización pipeline está presente y la instrucción throw está en una cláusula catch-clause, la excepción detectada por catch-clause se vuelve a generar después de ejecutar cualquier cláusula finally-clause asociada a catch-clause.
Si la canalización está presente, el tipo de la excepción lanzada está definido por la implementación.
Cuando se produce una excepción, el control se transfiere a la primera cláusula catch de una instrucción try envolvente que pueda controlar la excepción. La ubicación en la que se produce la excepción inicialmente se denomina el punto de lanzamiento . Una vez que se produce una excepción, los pasos descritos en §8.7 se siguen repetidamente hasta que se encuentre una cláusula catch que coincida con la excepción o no se encuentre ninguna.
Ejemplos:
throw
throw 100
throw "No such record in file"
Si se omite pipeline y la instrucción throw no está incluida en una cláusula catch-clause, se escribe el texto "ScriptHalted" en la canalización y el tipo de excepción que se genera es System.Management.Automation.RuntimeException
.
Si la canalización está presente, la excepción generada se encapsula en un objeto de tipo System.Management.Automation.RuntimeException
, que incluye información sobre la excepción como objeto System.Management.Automation.ErrorRecord
(accesible a través de $_
).
Ejemplo 1: throw 123
da como resultado una excepción de tipo RuntimeException. Dentro del bloque catch, $_.TargetObject
contiene el objeto encapsulado; en este caso System.Int32
con el valor 123.
Ejemplo 2: throw "xxx"
da como resultado una excepción de tipo RuntimeException. Dentro del bloque catch, $_.TargetObject
contiene el objeto encapsulado; en este caso System.String
con el valor "xxx".
Ejemplo 3: throw 10,20
da como resultado una excepción de tipo RuntimeException. Dentro del bloque catch, $_.TargetObject
contiene el objeto encapsulado; en este caso System.Object[]
, una matriz de dos elementos sin restricciones con los valores 10 y 20 de System
.Int32.
8.5.4 Instrucción return
Descripción:
La instrucción return
escribe en la canalización los valores designados por pipeline, si los hay, y devuelve el control al autor de llamada del script o la función. Una función o script puede tener cero o más instrucciones return
.
Si la ejecución llega hasta la llave de cierre de una función, se asume un valor return
implícito sin pipeline.
La instrucción return
simplifica la sintaxis para permitir que los programadores puedan expresarse como lo hacen en otros lenguajes; sin embargo, el valor que devuelve una función o script en realidad incluye todos los valores escritos en la canalización por esa función o script más cualquier valor especificado por la canalización pipeline. Si solo se escribe un valor escalar en la canalización, su tipo es el tipo del valor devuelto; De lo contrario, el tipo de valor devuelto es una matriz 1 dimensional sin restricciones que contiene todos los valores escritos en la canalización.
Ejemplos:
function Get-Factorial ($v) {
if ($v -eq 1) {
return 1 # return is not optional
}
return $v * (Get-Factorial ($v - 1)) # return is optional
}
El autor de llamada a Get-Factorial
obtiene un valor int
.
function Test {
"text1" # "text1" is written to the pipeline
# ...
"text2" # "text2" is written to the pipeline
# ...
return 123 # 123 is written to the pipeline
}
El autor de la llamada a Test
obtiene una matriz 1 dimensional sin restricciones de tres elementos.
8.5.5 Instrucción exit
Descripción:
La instrucción exit finaliza el script actual y devuelve el control y un código de salida al entorno host o al script de llamada. Si se proporciona pipeline, el valor que designa se convierte en int, si es necesario. Si no existe dicha conversión o si canalización se omite, se devuelve el valor int cero.
Ejemplos:
exit $count # terminate the script with some accumulated count
8.6 Instrucción switch
Sintaxis:
switch-statement:
switch new-lines~opt~ switch-parameters~opt~ switch-condition switch-body
switch-parameters:
switch-parameter
switch-parameters switch-parameter
switch-parameter:
-regex
-wildcard
-exact
-casesensitive
-parallel
switch-condition:
( new-lines~opt~ pipeline new-lines~opt~ )
-file new-lines~opt~ switch-filename
switch-filename:
command-argument
primary-expression
switch-body:
new-lines~opt~ { new-lines~opt~ switch-clauses }
switch-clauses:
switch-clause
switch-clauses switch-clause
switch-clause:
switch-clause-condition statement-block statement-terimators~opt~
switch-clause-condition:
command-argument
primary-expression
Descripción:
Si switch-condition designa un único valor, el control se pasa a uno o varios bloques de instrucciones de patrón coincidentes. Si no coinciden patrones, se puede realizar alguna acción predeterminada.
Un modificador debe contener una o varias cláusulas switch-clause, cada una empezando con un patrón (una cláusula switch no predeterminada) o la contraseña default
(una cláusula switch predeterminada). Un modificador debe contener cero o una cláusula switch default
y cero o más cláusulas switch no predeterminadas. Las cláusulas Switch se pueden escribir en cualquier orden.
Varios patrones pueden tener el mismo valor. Un patrón no puede ser un literal y un modificador puede tener patrones con tipos diferentes.
Si el valor de switch-condition coincide con un valor de patrón, se ejecuta el bloque de instrucciones de ese patrón. Si varios valores de patrón coinciden con el valor de switch-condition, se ejecuta el elemento statement-block de cada patrón coincidente, en orden léxico, a menos que uno de esos elementos statement-block contengan una instrucción break
statement (§8.5.1).
Si el valor de switch-condition no coincide con ningún valor de patrón, si existe una cláusula switch default
, se ejecuta su elemento statement-block. De lo contrario, se finaliza la coincidencia de patrones para esa switch-condition.
Los modificadores se pueden anidar y cada uno de ellos tiene su propio conjunto de cláusulas switch. En tales casos, una cláusula switch pertenece al modificador más interno actualmente en el ámbito.
En la entrada a cada elemento statement-block, se le asigna automáticamente a $_
el valor de condición switch-condition que hizo que el control pasará a ese elemento statement-block. $_
también está disponible en la switch-clause-condition de ese elemento statement-block.
La coincidencia de elementos no basados en cadenas se realiza realizando pruebas de igualdad (§7.8.1).
De manera predeterminada, si la coincidencia implica cadenas, la comparación no distingue entre mayúsculas y minúsculas. La presencia de switch-parameter-casesensitive
hace que la comparación distinga mayúsculas de minúsculas.
Un patrón puede contener caracteres comodín (§3.15), en cuyo caso se realizan comparaciones de cadenas comodín, pero solo si el parámetro de conmutación -wildcard está presente. De manera predeterminada, la comparación distingue mayúsculas de minúsculas.
Un patrón puede contener una expresión regular (-regex
está presente y hay coincidencia con un patrón, se define $matches
en el elemento statement-block de la switch-clause de ese patrón.
Se puede abreviar un parámetro switch-parameter; es posible utilizar cualquier parte inicial distintiva de un parámetro. Por ejemplo, ‑regex
, ‑rege
, ‑reg
, ‑re
y ‑r
son equivalentes.
Si se especifican parámetros switch-parameter en conflicto, tiene prioridad el último especificado en términos léxicos. La presencia de ‑exact
deshabilita -regex
y -wildcard
; no tiene ningún efecto en ‑case
, sin embargo.
Si se especifica el parámetro switch-parameter‑parallel
, el comportamiento lo define la implementación.
El parámetro de conmutación
Si un patrón es un script-block-expression, ese bloque se evalúa y el resultado se convierte en bool, si es necesario. Si el resultado tiene el valor $true
, se ejecuta el bloque de instrucciones correspondiente; de lo contrario, no se ejecuta.
Si condición de conmutación designa varios valores, el conmutador se aplica a cada valor en orden léxico utilizando las reglas descritas anteriormente para una condición de conmutación que designa un solo valor. Cada sentencia switch tiene su propio enumerador, $switch
(§2.3.2.2, §4.5.16), que solo existe mientras se ejecuta esa sentencia.
Una instrucción switch puede tener una etiqueta y puede incluir instrucciones break (§8.5.1) y continue (§8.5.2) con y sin etiqueta.
Si la condición switch-condition es -file
switch-filename, en lugar de recorrer en iteración los valores de una expresión, el modificador recorre en iteración los valores del archivo que se designa en switch-filename. El archivo se lee una línea a la vez y cada línea comprende un valor. Los caracteres de terminador de línea no se incluyen en los valores.
Ejemplos:
$s = "ABC def`nghi`tjkl`fmno @#$"
$charCount = 0; $pageCount = 0; $lineCount = 0; $otherCount = 0
for ($i = 0; $i -lt $s.Length; ++$i) {
++$charCount
switch ($s[$i]) {
"`n" { ++$lineCount }
"`f" { ++$pageCount }
"`t" { }
" " { }
default { ++$otherCount }
}
}
switch -wildcard ("abc") {
a* { "a*, $_" }
?B? { "?B? , $_" }
default { "default, $_" }
}
switch -regex -casesensitive ("abc") {
^a* { "a*" }
^A* { "A*" }
}
switch (0, 1, 19, 20, 21) {
{ $_ -lt 20 } { "-lt 20" }
{ $_ -band 1 } { "Odd" }
{ $_ -eq 19 } { "-eq 19" }
default { "default" }
}
8.7 La instrucción try/finally
Sintaxis:
try-statement:
try statement-block catch-clauses
try statement-block finally-clause
try statement-block catch-clauses finally-clause
catch-clauses:
catch-clause
catch-clauses catch-clause
catch-clause:
new-lines~opt~ catch catch-type-list~opt~
statement-block
catch-type-list:
new-lines~opt~ type-literal
catch-type-list new-lines~opt~ , new-lines~opt~
type-literalfinally-clause:
new-lines~opt~ finally statement-block
Descripción:
La instrucción try proporciona un mecanismo para detectar excepciones que se producen al ejecutar un elemento de bloque. La instrucción try también proporciona la capacidad de especificar un bloque de código que siempre se ejecuta cuando el control sale de la instrucción try. El proceso de generar una excepción a través de la instrucción throw se describe en §8.5.3.
Un bloque try es el elemento statement-block asociado con la instrucción try. Un bloque catch es el elemento statement-block asociado con una cláusula catch-clause. Un bloque finally es el elemento statement-block asociado con una cláusula finally-clause.
Una cláusula catch-clause sin una lista catch-type-list se conoce como cláusula catch general.
Cada cláusula catch-clause es un controlador de excepciones y una cláusula catch-clause cuya lista catch-type-list contiene el tipo de excepción generada es una cláusula catch coincidente. Una cláusula catch general coincide con todos los tipos de excepción.
Aunque las cláusulas catch-clauses y finally-clause son opcionales, debe estar presente al menos una de ellas.
El procesamiento de una excepción lanzada consiste en evaluar los pasos siguientes repetidamente hasta que se encuentre una cláusula de captura que coincida con la excepción.
En el ámbito actual, se examina cada instrucción try que incluye el punto de inicio. Para cada instrucción try S, empezando por la instrucción try más interna y terminando con la instrucción try más externa, se evalúan los pasos siguientes:
Si el bloque
try
de S incluye el punto de inicio y si S tiene una o varias cláusulas catch, estas cláusulas catch se examinan en orden léxico para buscar un controlador adecuado para la excepción. La primera cláusula catch que especifica el tipo de excepción o un tipo base del tipo de excepción se considera una coincidencia. Una cláusula catch general se considera una coincidencia para cualquier tipo de excepción. Si se encuentra una cláusula catch coincidente, el procesamiento de excepciones se completa transfiriendo el control al bloque de esa cláusula catch. Dentro de una cláusula catch coincidente, la variable$_
contiene una descripción de la excepción actual.De lo contrario, si el bloque
try
o un bloquecatch
de S encierra el punto de lanzamiento y si S tiene un bloquefinally
, se transfiere el control al bloque finally. Si el bloquefinally
produce otra excepción, se finaliza el procesamiento de la excepción actual. De lo contrario, cuando el control llega al final del bloquefinally
, se continúa el procesamiento de la excepción actual.
Si no se encontró un controlador de excepciones en el ámbito actual, se repiten los pasos anteriores para el ámbito que incluye un punto de inicio correspondiente a la instrucción desde la que se invocó el ámbito actual.
Si el procesamiento de excepciones finaliza todos los ámbitos, lo que indica que no existe ningún controlador para la excepción, el comportamiento queda sin especificar.
Para evitar cláusulas catch inaccesibles en un bloque try, es posible que una cláusula catch no especifique un tipo de excepción igual o derivado de un tipo especificado en una cláusula catch anterior dentro de ese mismo bloque try.
Las instrucciones de un bloque finally
siempre se ejecutan cuando el control deja una instrucción try
. Esto es cierto si la transferencia de control se produce como resultado de la ejecución normal, como resultado de ejecutar una instrucción break
, continue
o return
, o como resultado de una excepción que se produce en la instrucción try
.
Si se genera una excepción al ejecutar un bloque finally
, la excepción se genera en la instrucción try
de inclusión siguiente. Si otra excepción estaba siendo manejada, esa excepción se pierde. El proceso de generación de una excepción se explica con más detalle en la instrucción throw
.
Las declaraciones try
pueden coexistir con las declaraciones trap
; consulte §8.8 para obtener más información.
Ejemplos:
$a = new-object 'int[]' 10
$i = 20 # out-of-bounds subscript
while ($true) {
try {
$a[$i] = 10
"Assignment completed without error"
break
}
catch [IndexOutOfRangeException] {
"Handling out-of-bounds index, >$_<`n"
$i = 5
}
catch {
"Caught unexpected exception"
}
finally {
# ...
}
}
Cada excepción iniciada se genera como System.Management.Automation.RuntimeException
. Si hay cláusulas catch-clause específicas del tipo en el bloque try
, se inspecciona la propiedad InnerException de la excepción para intentar encontrar una coincidencia, tal como ocurre con el tipoSystem.IndexOutOfRangeException
mencionado anteriormente.
8.8 La instrucción trap
Sintaxis:
trap-statement:
*trap* new-lines~opt~ type-literal~opt~ new-lines~opt~ statement-block
Descripción:
Una instrucción trap
con y sin type-literal es análoga a un bloque catch
(§8.7) con y sin catch-type-list, respectivamente, excepto en que una instrucción trap
solo puede interceptar un tipo a la vez.
Se pueden definir varias instrucciones trap
en el mismo bloque de instruccionesy su orden de definición es irrelevante. Si se definen dos instrucciones trap
con el mismo type-literal en el mismo ámbito, se usa la primera en orden léxico para procesar una excepción de tipo coincidente.
A diferencia de un bloque catch
, una instrucción trap
coincide exactamente con un tipo de excepción; no se realiza ninguna coincidencia de tipos derivados.
Cuando se produce una excepción, si no hay ninguna instrucción trap
coincidente en el ámbito actual, se busca una instrucción trap coincidente en el ámbito de inclusión, lo que puede implicar buscar en el script de llamada, la función o el filtro y, luego, en el autor de llamada, y así sucesivamente. Si la búsqueda se completa y finaliza todos los ámbitos, lo que indica que no hay controlador para la excepción, no se especifica el comportamiento.
El cuerpo statement-body de una instrucción trap
se ejecuta solo para procesar la excepción correspondiente; de lo contrario, la ejecución la pasa por alto.
Si el cuerpo statement-body de una instrucción trap
se cierra de forma normal, de manera predeterminada se escribe un objeto de error en la secuencia de error, la excepción se considera controlada y la ejecución continúa con la instrucción inmediatamente posterior a la del ámbito que contiene la instrucción trap
que hizo visible la excepción. La causa de la excepción podría estar en un comando llamado por el comando que contiene la instrucción trap
.
Si la instrucción final ejecutada en el cuerpo statement-body de una instrucción trap
es continua (§8.5.2), se suprime la escritura del objeto de error en la secuencia de error y la ejecución continúa con la instrucción inmediatamente posterior a la del ámbito que contiene la instrucción trap que hizo visible la excepción. Si la instrucción final ejecutada en el cuerpo statement-body de una instrucción trap
se interrumpe (§8.5.1), se suprime la escritura del objeto de error en la secuencia de error y se vuelve a generar la excepción.
Dentro de una instrucción trap
la variable $_
contiene una descripción del error actual.
Tenga en cuenta el caso en el que una excepción generada desde un bloque de try
no tiene un bloque de catch
coincidente, pero existe una instrucción trap
coincidente en un nivel de bloque superior. Una vez que se ejecuta la cláusula finally del bloque try
, la instrucción trap
obtiene el control incluso si algún ámbito primario tiene un bloque catch
coincidente. Si se define una instrucción trap
dentro del propio bloque try
y ese bloque try
tiene un bloque de catch
coincidente, la instrucción trap
obtiene el control .
Ejemplos:
En el ejemplo siguiente, se escribe el objeto de error y la ejecución continúa con la instrucción inmediatamente posterior a la que generó la intercepción; es decir, se escribe "Donde" (Listo) en la canalización.
$j = 0; $v = 10/$j; "Done"
trap { $j = 2 }
En el ejemplo siguiente, se suprime la escritura del objeto de error y la ejecución continúa con la instrucción inmediatamente posterior a la que generó la intercepción; es decir, se escribe "Donde" (Listo) en la canalización.
$j = 0; $v = 10/$j; "Done"
trap { $j = 2; continue }
En el ejemplo siguiente, se suprime la escritura del objeto de error y se vuelve a generar la excepción.
$j = 0; $v = 10/$j; "Done"
trap { $j = 2; break }
En el ejemplo siguiente, las instrucciones trap y exception-generating se encuentran en el mismo ámbito. Una vez detectada y controlada la excepción, la ejecución se reanuda escribiendo el número 1 en la canalización.
&{trap{}; throw '\...'; 1}
En el ejemplo siguiente, las instrucciones trap y exception-generating se encuentran en ámbitos distintos. Una vez detectada y controlada la excepción, se reanuda la ejecución escribiendo 2 (no 1) en la canalización.
trap{} &{throw '\...'; 1}; 2
8.9 La declaración de datos
Sintaxis:
data-statement:
data new-lines~opt~ data-name data-commands-allowed~opt~ statement-block
data-name:
simple-name
data-commands-allowed:
new-lines~opt~ -supportedcommand data-commands-list
data-commands-list:
new-lines~opt~ data-command
data-commands-list , new-lines~opt~ data-command
data-command:
command-name-expr
Descripción:
Una instrucción de datos crea una sección de datos , manteniendo los datos de esa sección separados del código. Esta separación admite instalaciones como archivos de recursos de cadena independientes para texto, como mensajes de error y cadenas de ayuda. También ayuda a apoyar la internacionalización haciendo que sea más fácil aislar, localizar y procesar cadenas que se traducirán en diferentes idiomas.
Un script o función puede tener cero o más secciones de datos.
El bloque de instrucciones de una sección de datos está limitado a contener solo las siguientes características de PowerShell:
- Todos los operadores excepto
-match
- Instrucción
if
- Las siguientes variables automáticas:
$PsCulture
,$PsUICulture
,$true
,$false
y$null
. - Comentarios
- Tuberías
- Declaraciones separadas por punto y coma (
;
) - Literales
- Llamadas al cmdlet ConvertFrom-StringData
- Cualquier otro cmdlet identificado mediante el parámetro supportedcommand
Si se usa el cmdlet ConvertFrom-StringData
, los pares clave-valor se pueden expresar mediante cualquier forma de literal de cadena. Sin embargo, los literales expandable-string-literal y expandable-here-string-literal no pueden contener ninguna sustitución de variables ni expansiones de subexpresiones.
Ejemplos:
El parámetro SupportedCommand indica que los cmdlets o funciones especificados solo generan datos.
Por ejemplo, la siguiente sección de datos incluye un cmdlet escrito por el usuario, ConvertTo-XML
, que da formato a los datos en un archivo XML:
data -supportedCommand ConvertTo-XML {
Format-XML -strings string1, string2, string3
}
Considere el ejemplo siguiente, en el que la sección de datos contiene un comando ConvertFrom-StringData
que convierte las cadenas en una tabla hash, cuyo valor se asigna a $messages
.
$messages = data {
ConvertFrom-StringData -stringdata @'
Greeting = Hello
Yes = yes
No = no
'@
}
Se accede a las claves y los valores de la tabla hash mediante $messages.Greeting
, $messages.Yes
y $messages.No
, respectivamente.
Ahora, esto se puede guardar como un recurso en inglés. Los recursos en alemán y español se pueden crear en archivos independientes, con las secciones de datos siguientes:
$messages = data {
ConvertFrom-StringData -stringdata @"
Greeting = Guten Tag
Yes = ja
No = nein
"@
}
$messagesS = data {
ConvertFrom-StringData -stringdata @"
Greeting = Buenos días
Yes = sí
No = no
"@
}
Si nombrede datos está presente, asigna un nombre a la variable (sin usar un $
inicial) en el que se almacenará el valor de la instrucción de datos. En concreto, $name = data { ... }
es equivalente a data name { ... }
.
8.10 Definiciones de función
Sintaxis:
function-statement:
function new-lines~opt~ function-name function-parameter-declaration~opt~ { script-block }
filter new-lines~opt~ function-name function-parameter-declaration~opt~ { script-block }
workflow new-lines~opt~ function-name function-parameter-declaration~opt~ { script-block }
function-name:
command-argument
command-argument:
command-name-expr
function-parameter-declaration:
new-lines~opt~ ( parameter-list new-lines~opt~ )
parameter-list:
script-parameter
parameter-list new-lines~opt~ , script-parameter
script-parameter:
new-lines~opt~ attribute-list~opt~ new-lines~opt~ variable script-parameter-default~opt~
script-block:
param-block~opt~ statement-terminators~opt~ script-block-body~opt~
param-block:
new-lines~opt~ attribute-list~opt~ new-lines~opt~ param new-lines~opt~
( parameter-list~opt~ new-lines~opt~ )
parameter-list:
script-parameter
parameter-list new-lines~opt~ , script-parameter
script-parameter-default:
new-lines~opt~ = new-lines~opt~ expression
script-block-body:
named-block-list
statement-list
named-block-list:
named-block
named-block-list named-block
named-block:
block-name statement-block statement-terminators~opt~
block-name: one of
dynamicparam begin process end
Descripción:
Una definición de función especifica el nombre de la función, el filtro o el flujo de trabajo que se define y los nombres de sus parámetros, si los hay. También contiene cero o más instrucciones que se ejecutan para lograr el propósito de esa función.
Cada función es una instancia de la clase System.Management.Automation.FunctionInfo
.
8.10.1 Funciones de filtro
Mientras que una función normal se ejecuta una vez en una canalización y accede a la colección de entrada a través de $input
, un filtro es un tipo especial de función que se ejecuta una vez para cada objeto de la colección de entrada.
El objeto que se está procesando actualmente está disponible a través de la variable $_
.
Un filtro sin bloques con nombre (§8.10.7) es equivalente a una función con un bloque de proceso, pero sin ningún bloque inicial ni bloque final.
Tenga en cuenta la siguiente definición y llamadas de función de filtro:
filter Get-Square2 { # make the function a filter
$_ * $_ # access current object from the collection
}
-3..3 | Get-Square2 # collection has 7 elements
6, 10, -3 | Get-Square2 # collection has 3 elements
Cada filtro es una instancia de la clase System.Management.Automation.FilterInfo
(§4.5.11).
8.10.2 Funciones de flujo de trabajo
Una función de flujo de trabajo es como una función normal con semántica definida por la implementación. Una función de flujo de trabajo se traduce a una secuencia de actividades de Windows Workflow Foundation y se ejecuta en el motor de Windows Workflow Foundation.
8.10.3 Procesamiento de argumentos
Tenga en cuenta la siguiente definición para una función denominada Get-Power
:
function Get-Power ([long]$base, [int]$exponent) {
$result = 1
for ($i = 1; $i -le $exponent; ++$i) {
$result *= $base
}
return $result
}
Esta función tiene dos parámetros, $base
y $exponent
. También contiene un conjunto de instrucciones que, para exponentes con valores no negativos, calcula $base^$exponent^
y devuelve el resultado a quien llamó a Get-Power
.
Cuando un script, una función o un filtro comienza la ejecución, cada parámetro se inicializa en el valor del argumento correspondiente. Si no hay ningún argumento correspondiente y se proporciona un valor predeterminado (§8.10.4), ese valor se usa; De lo contrario, se usa el valor $null
. Por lo tanto, cada parámetro es una nueva variable como si se inicializara mediante la asignación al principio del script-block .
Si un parámetro script-parameter contiene una restricción de tipo (como [long]
y [int]
anterior), el valor del argumento correspondiente se convierte en ese tipo, si es necesario; de lo contrario, no se produce ninguna conversión.
Cuando un script, una función o un filtro comienza la ejecución, la variable $args
se define dentro de ella como una matriz 1 dimensional sin restricciones, que contiene todos los argumentos no enlazados por nombre o posición, en orden léxico.
Tenga en cuenta la siguiente definición de función y llamadas:
function F ($a, $b, $c, $d) { ... }
F -b 3 -d 5 2 4 # $a is 2, $b is 3, $c is 4, $d is 5, $args Length 0
F -a 2 -d 3 4 5 # $a is 2, $b is 4, $c is 5, $d is 3, $args Length 0
F 2 3 4 5 -c 7 -a 1 # $a is 1, $b is 2, $c is 7, $d is 3, $args Length 2
Para obtener más información sobre el enlace de parámetros, consulte §8.14.
Inicializadores de parámetros 8.10.4
La declaración de un parámetro p puede contener un inicializador, en cuyo caso, el valor del inicializador se usa para inicializar p siempre que p no esté enlazado a ningún argumento de la llamada.
Tenga en cuenta la siguiente definición de función y llamadas:
function Find-Str ([string]$str, [int]$start_pos = 0) { ... }
Find-Str "abcabc" # 2nd argument omitted, 0 used for $start_pos
Find-Str "abcabc" 2 # 2nd argument present, so it is used for $start_pos
8.10.5 Restricción de tipo [switch]
Cuando se pasa un parámetro switch, el parámetro correspondiente del comando debe estar restringido por el modificador de tipo. El modificador de tipo tiene dos valores, True y False.
Tenga en cuenta la siguiente definición de función y llamadas:
function Process ([switch]$trace, $p1, $p2) { ... }
Process 10 20 # $trace is False, $p1 is 10, $p2 is 20
Process 10 -trace 20 # $trace is True, $p1 is 10, $p2 is 20
Process 10 20 -trace # $trace is True, $p1 is 10, $p2 is 20
Process 10 20 -trace:$false # $trace is False, $p1 is 10, $p2 is 20
Process 10 20 -trace:$true # $trace is True, $p1 is 10, $p2 is 20
8.10.6 Canalizaciones y funciones
Cuando se usa un script, una función o un filtro en una canalización, se entrega una colección de valores a ese script o función. El script, la función o el filtro obtiene acceso a esa colección a través del enumerador $input (§2.3.2.2, §4.5.16), que se define en la entrada a ese script, función o filtro.
Tenga en cuenta la siguiente definición de función y llamadas:
function Get-Square1 {
foreach ($i in $input) { # iterate over the collection
$i * $i
}
}
-3..3 | Get-Square1 # collection has 7 elements
6, 10, -3 | Get-Square1 # collection has 3 elements
8.10.7 Bloques con nombre
Las declaraciones de un bloque de script pueden pertenecer a un bloque grande sin nombre o pueden distribuirse en uno o varios bloques con nombre. Los bloques con nombre permiten el procesamiento personalizado de colecciones procedentes de canalizaciones; Los bloques con nombre se pueden definir en cualquier orden.
Las instrucciones que se encuentran en un bloque begin (es decir, uno marcado con la palabra clave begin) se ejecutan una vez, antes de que se entregue el primer objeto de canalización.
Las instrucciones que se encuentran en un bloque process (es decir, uno marcado con la palabra clave process) se ejecutan para cada objeto de canalización entregado. ($_
proporciona acceso al objeto actual que se está procesando desde la colección de entrada procedente de la canalización). Esto significa que si una colección de cero elementos se envía a través de la canalización, el bloque de proceso no se ejecuta en absoluto. Sin embargo, si se llama al script o la función fuera de un contexto de canalización, este bloque se ejecuta exactamente una vez y $_
se establece en $null
, ya que no hay ningún objeto de colección actual.
Las instrucciones que se encuentran en un bloque end (es decir, uno marcado con la palabra clave end) se ejecutan una vez, después de que se entrega el último objeto de canalización.
8.10.8 Bloque dynamicparam
Hasta ahora, las subsecciones de §8.10 hablan de parámetros estáticos, que se definen como parte del código fuente. También es posible definir parámetros dinámicos a través de un bloque dynamicparam, otra forma de bloque con nombre (§8.10.7), que se marca con la palabra clave dynamicparam
. Gran parte de esta maquinaria está definida en la implementación.
Los parámetros dinámicos son parámetros de un cmdlet, una función, un filtro o un script que solo están disponibles en determinadas condiciones. Uno de estos casos es el parámetro Encoding del cmdlet Set-Item
.
En el bloque de instrucciones , use una instrucción If para especificar las condiciones en las que el parámetro está disponible en la función. Use el cmdlet New-Object para crear un objeto de un tipo definido por la implementación para representar el parámetro y especificar su nombre. Además, use New-Object
para crear un objeto de un tipo definido por la implementación diferente para representar los atributos definidos por la implementación del parámetro.
En el ejemplo siguiente se muestra una función con parámetros estándar denominados Name y Path, y un parámetro dinámico opcional denominado DP1. El parámetro DP1 está en el conjunto de parámetros PSet1 y tiene un tipo de Int32
. El parámetro DP1 está disponible en la función Sample solo cuando el valor del parámetro Path contiene "HKLM:", lo que indica que se está usando en la unidad del Registro HKEY_LOCAL_MACHINE
.
function Sample {
Param ([String]$Name, [String]$Path)
dynamicparam {
if ($path -match "*HKLM*:") {
$dynParam1 = New-Object System.Management.Automation.RuntimeDefinedParameter("dp1", [Int32], $attributeCollection)
$attributes = New-Object System.Management.Automation.ParameterAttribute
$attributes.ParameterSetName = 'pset1'
$attributes.Mandatory = $false
$attributeCollection = New-Object -Type System.Collections.ObjectModel.Collection``1[System.Attribute]
$attributeCollection.Add($attributes)
$paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
$paramDictionary.Add("dp1", $dynParam1)
return $paramDictionary
}
}
}
El tipo usado para crear un objeto para representar un parámetro dinámico es System.Management.Automation.RuntimeDefinedParameter
.
El tipo usado para crear un objeto para representar los atributos del parámetro es System.Management.Automation.ParameterAttribute
.
Los atributos del parámetro definidos por la implementación incluyen Mandatory, Position y ValueFromPipeline.
Bloque de parámetros 8.10.9
Un param-block proporciona una manera alternativa de declarar parámetros. Por ejemplo, los siguientes conjuntos de declaraciones de parámetros son equivalentes:
function FindStr1 ([string]$str, [int]$start_pos = 0) { ... }
function FindStr2 {
param ([string]$str, [int]$start_pos = 0) ...
}
Un bloque param-block permite una lista attribute-list en el bloque param-block, mientras que una declaración function-parameter-declaration no lo hace.
Un script puede tener un bloque param-block, pero no una declaración function-parameter-declaration. Una definición de filtro o función puede tener una claración function-parameter-declaration o un bloque param-block, pero no ambos.
Tenga en cuenta el ejemplo siguiente:
param ( [Parameter(Mandatory = $true, ValueFromPipeline=$true)]
[string[]] $ComputerName )
El único parámetro, $ComputerName
, tiene el tipo string[]
, es necesario y toma la entrada de la canalización.
Consulte §12.3.7 para obtener una explicación del atributo Parameter y para obtener más ejemplos.
8.11 La instrucción parallel
Sintaxis:
parallel-statement:
*parallel* statement-block
La instrucción paralela contiene cero o más instrucciones que se ejecutan de forma definida por la implementación.
Solo se permite una instrucción paralela en un flujo de trabajo (§8.10.2).
8.12 La instrucción de secuencia
Sintaxis:
sequence-statement:
*sequence* statement-block
La instrucción sequence contiene cero o más instrucciones que se ejecutan de forma definida por la implementación.
Solo se permite una instrucción de secuencia en un flujo de trabajo (§8.10.2).
8.13 La instrucción InlineScript
Sintaxis:
inlinescript-statement:
inlinescript statement-block
La instrucción inlinescript contiene cero o más instrucciones que se ejecutan de forma definida por la implementación.
Una instrucción InlineScript solo se permite en un flujo de trabajo (§8.10.2).
8.14 Enlace de parámetros
Cuando se invoca un script, una función, un filtro o un cmdlet, cada argumento se puede enlazar al parámetro correspondiente por posición, con el primer parámetro que tiene la posición cero.
Tenga en cuenta el siguiente fragmento de definición para una función denominada Get-Power
y las llamadas a ella:
function Get-Power ([long]$base, [int]$exponent) { ... }
Get-Power 5 3 # argument 5 is bound to parameter $base in position 0
# argument 3 is bound to parameter $exponent in position 1
# no conversion is needed, and the result is 5 to the power 3
Get-Power 4.7 3.2 # double argument 4.7 is rounded to int 5, double argument
# 3.2 is rounded to int 3, and result is 5 to the power 3
Get-Power 5 # $exponent has value $null, which is converted to int 0
Get-Power # both parameters have value $null, which is converted to int 0
Cuando se invoca un script, una función, un filtro o un cmdlet, un argumento se puede enlazar al parámetro correspondiente por nombre. Para ello, se usa un parámetro con el argumento, que es un argumento que es el nombre del parámetro con un guión inicial (-), seguido del valor asociado para ese argumento. El nombre del parámetro usado puede tener cualquier ortografía que no distingue mayúsculas de minúsculas y puede usar cualquier prefijo que designe de forma única el parámetro correspondiente. Al elegir nombres de parámetros, evite usar los nombres de los parámetros comunes .
Tenga en cuenta las siguientes llamadas a la función Get-Power
:
Get-Power -base 5 -exponent 3 # -base designates $base, so 5 is
# bound to that, exponent designates
# $exponent, so 3 is bound to that
Get-Power -Exp 3 -BAs 5 # $base takes on 5 and $exponent takes on 3
Get-Power -e 3 -b 5 # $base takes on 5 and $exponent takes on 3
Por otro lado, las llamadas a la función siguiente
function Get-Hypot ([double]$side1, [double]$side2) {
return [Math]::Sqrt($side1 * $side1 + $side2 * $side2)
}
debe usar parámetros -side1
y -side2
, ya que no hay ningún prefijo que designe de forma única el parámetro.
El mismo nombre de parámetro no se puede usar varias veces con o sin valores de argumento asociados diferentes.
Los parámetros pueden tener atributos (§12). Para obtener información sobre los atributos individuales, consulte las secciones de §12.3. Para obtener información sobre los conjuntos de parámetros, consulte §12.3.7.
Un script, función, filtro o cmdlet puede recibir argumentos a través de la línea de comandos de invocación, desde la canalización o desde ambos. Estos son los pasos, en orden, para resolver el enlace de parámetros:
- Enlace todos los parámetros nombrados y, a continuación,
- Vincula los parámetros posicionales, luego
- Enlace desde la canalización por valor (§12.3.7) con coincidencia exacta y, a continuación,
- Enlace desde la canalización por valor (§12.3.7) con conversión y, a continuación,
- Enlace desde la canalización por nombre (§12.3.7) con coincidencia exacta y, a continuación,
- Enlace desde la canalización por nombre (§12.3.7) con conversión
Varios de estos pasos implican la conversión, como se describe en §6. Sin embargo, el conjunto de conversiones que se usan en el enlace no es exactamente el mismo que el usado en las conversiones de idioma. Específicamente
- Aunque el valor
$null
se puede convertir a bool,$null
no se puede enlazar abool
. - Cuando el valor
$null
se pasa a un parámetro de conmutación para un cmdlet, se interpreta como si se hubiera pasado$true
. Sin embargo, cuando se pasa a un parámetro de modificador para una función, se trata como si se pasara$false
. - Los parámetros de tipo bool o switch solo se pueden enlazar a argumentos numéricos o bool.
- Si el tipo de parámetro no es una colección, pero el argumento es de algún tipo de colección, no se intenta realizar ninguna conversión a menos que el tipo de parámetro sea object o PsObject. (El punto principal de esta restricción es no permitir la conversión de una colección a un parámetro de cadena). De lo contrario, se intentan las conversiones habituales.
Si el tipo de parámetro es IList
o ICollection<T>
, solo se intentan realizar esas conversiones a través de Constructor, op_Implicit y op_Explicit. Si no existen estas conversiones, se usa una conversión especial para parámetros de tipo "colección", que incluye IList
, ICollection<T>
y matrices.
Los parámetros posicionales prefieren enlazarse sin conversión de tipos, si es posible. Por ejemplo
function Test {
[CmdletBinding(DefaultParameterSetname = "SetB")]
param([Parameter(Position = 0, ParameterSetname = "SetA")]
[decimal]$dec,
[Parameter(Position = 0, ParameterSetname = "SetB")]
[int]$in
)
$PsCmdlet.ParameterSetName
}
Test 42d # outputs "SetA"
Test 42 # outputs "SetB"