Windows PowerShell: Curso intensivo sobre secuencias de comandos

Esta entrega extendida sobre Windows PowerShell dará un impulso a sus conocimientos sobre esta poderosa tecnología.

Don Jones

Más de los están acostumbrando a Windows PowerShell y darse cuenta de sus ventajas.Con eso en mente, de mes este se van a ser larga.Se trata de una visión general de lightning de secuencias de comandos de Windows PowerShell, incluido cómo crear secuencias de comandos parametrizados.En los próximos meses, me centraré en temas específicos que se basan en esta base.

Si no se utilizan para ejecutar comandos de Windows PowerShell en la consola, puede resultar demasiado avanzado, pero intente apartar a través de todos modos.Debe tener un conocimiento exhaustivo de las características de seguridad de Windows PowerShell.Ya debe saber acerca de la directiva de ejecución y sabe qué configuración se está utilizando.Si aún no conoce la diferencia entre "RemoteSigned" y "AllSigned", y por qué uno podría ser mejor que el otro, no esté listo para el material.

También debe saber cómo ejecutar secuencias de comandos en el shell y debe recordar que siempre tendrá que proporcionar una ruta de acceso y nombre de archivo para ejecutar una secuencia de comandos.Por último, también debe saber la diferencia entre ejecutar una secuencia de comandos en la consola y el Integrated Scripting Environment (ISE).En la ISE, secuencias de comandos se ejecutan en el ámbito global.En la consola de shell normal, secuencias de comandos de obtener su propio ámbito.Haré una revisión de ámbito, pero ya debe tener una idea de lo que significa y qué hace.

Si no se siente muy acelerar, eche un vistazo a mi libro, "De Windows PowerShell de aprender en un mes de comidas" (Manning Publications, 2011) y el companion Web site y vea si dichos recursos pueden ayudarle a crear una mejor base.

Intente seguir a lo largo de leer esta columna.Probar los ejemplos.Si escribe (o copiar y pegar) en los ejemplos de secuencias de comandos en la ISE de Windows PowerShell empieza en la línea 1, los números de línea se corresponden con los números de línea en las descripciones.

Archivos de secuencia de comandos de Windows PowerShell

Un archivo de secuencia de comandos de Windows PowerShell no es más que un archivo de texto que tiene una.Extensión de nombre de archivo PS1.El "1" no hace referencia a la versión de Windows PowerShell, pero en su lugar la versión del motor de lenguaje.Windows PowerShell versión 1 y 2 utilizar la versión del motor de lenguaje 1.Por eso las dos versiones del shell se instalan en una carpeta v1.0 bajo \Windows\System32\WindowsPowerShell.

Una secuencia de comandos de Windows PowerShell no es exactamente igual que un archivo por lotes de la línea de comandos, y no ejecuta una secuencia de comandos es precisamente lo mismo que ejecutar los mismos comandos en la misma secuencia.Por ejemplo, abra una ventana de consola y ejecute el siguiente, presione ENTRAR después de cada línea (Recuerde no escriba los números de línea):

Get-Service
Get-Process

Ahora escriba estas mismas líneas exactas en un archivo de secuencia de comandos o la secuencia de comandos ISE panel de edición y ejecutar la secuencia de comandos. Obtendrá resultados de aspecto diferente. Cada vez que se presione la tecla Intro en Windows PowerShell, que inicia una nueva canalización. Se ejecutan los comandos que ha escrito en esa sola tubería. Al final de la canalización, Windows PowerShell convierte su contenido en una pantalla de texto. Al ejecutar los dos comandos en la consola normal, una vez hecho esto en dos canalizaciones distintas.

Windows PowerShell fue capaz de construir una pantalla única para cada conjunto de resultados. Cuando se introducen en una secuencia de comandos, sin embargo, ambos comandos se ejecutaban en la misma tubería. El Windows PowerShell formato del sistema no está sofisticado suficiente para construir el único mismo resultado para dos conjuntos de resultados diferentes. Intente ejecutar este código en la consola:

Get-Service;Get-Process

Los resultados deben el mismo aspecto que tenían cuando se ejecutó la secuencia de comandos que contiene los dos comandos. En este caso, ambos comandos se ejecutaban en una sola tubería. Es lo que sucedió cuando ejecutó la secuencia de comandos.

El resultado práctico de todo esto es que una secuencia de comandos debe generar sólo un tipo de salida. Es una mala idea, debido en gran medida a las limitaciones del sistema de formato. Hay otras consideraciones. No se desea una secuencia de comandos volcar diferentes tipos de cosas en la canalización al mismo tiempo.

Centrarse en la que como una regla para todo lo que vamos a abordar. Una secuencia de comandos debe generar una y solamente una, tipo de salida. La única excepción sería si es una secuencia de comandos que se utiliza como un repositorio para múltiples funciones. En ese caso, cada función debe generar una y solamente una, tipo de salida.

Variables

Considere las variables como un cuadro. Puede colocar uno o más elementos, incluso cosas diferentes, en este cuadro. El cuadro tiene un nombre y, en Windows PowerShell ese nombre puede incluir casi cualquier cosa. "Var" puede ser un nombre de variable, como se puede "{my variable}". En el segundo ejemplo, las llaves encierran un nombre de variable que contiene espacios, que es bastante feo. Como recomendación, se pegan con los nombres de variables que incluyen letras, números y caracteres de subrayado.

Utilizando el nombre de una variable hace referencia a todo el "box". Si desea hacer referencia al contenido del cuadro, agregar un signo de dólar: $ var. A menudo verá precedidas por el signo de dólar, porque el punto completo del uso de uno es obtener el contenido de variables de Windows PowerShell. Es importante no obstante, recuerde que el signo de dólar no forma parte del nombre de la variable. Es sólo una pista para indicar a Windows PowerShell que desea que el contenido, en lugar de en el propio cuadro. Por ejemplo:

$var = 'hello'
$number = 1
$numbers = 1,2,3,4,5,6,7,8,9

Estos ejemplos muestran cómo colocar elementos en una variable utilizando el operador de asignación (=). Este último ejemplo crea una matriz, porque Windows PowerShell interpreta todas las listas separadas por comas como una matriz o colección de elementos. El primer ejemplo asigna un objeto de cadena, con los caracteres de la cadena incluida entre comillas.

Hay un aspecto de Windows PowerShell que puede confundir a los recién llegados. Windows PowerShell no "comprende" ningún significado que se puede asociar con un nombre de variable. Una variable como computername $ no "saber" el shell de la variable que contenga un nombre de equipo.

De forma similar, los números de $ no "saber" el shell de una variable que contenga más de un número. El shell no importa si utiliza un nombre plural de la variable. La instrucción

$numbers = 1

También es válido para el shell, como es

$numbers = 'fred.'

Sin embargo, cuando una variable contiene varios valores, puede utilizar una sintaxis especial para tener acceso a sólo una sola de ellas. Utilizaría números $[0] como el primer elemento, números $[1] son el segundo, números $-[1] son el último, los números de $-[2] son el penúltimo y así sucesivamente.

Comillas

Como práctica recomendada, utilice comillas para delimitar una variable a menos que tenga una razón concreta para realizar lo contrario. Hay tres casos específicos donde se desea utilizar comillas dobles.

La primera es cuando se necesita insertar contenido de una variable en una cadena. Dentro de comillas dobles, Windows PowerShell buscará el $ y supondrá que es todo tras el $, hasta el primer carácter que no es válido en un nombre de variable, un nombre de variable. El contenido de esa variable reemplazará el nombre de variable y los $:

$name = 'Don'
$prompt = "My name is $name"

El símbolo del sistema de $ contendrá "mi nombre es Don" porque el nombre $ se reemplazará con el contenido de la variable. Esto es un truco muy útil para unir cadenas sin tener que concatenarlas.

Dentro de comillas dobles, Windows PowerShell también buscará su carácter de escape, las comillas invertidas o con acento grave y actuar en consecuencia. Éstos son algunos ejemplos:

$debug = "`$computer contains $computer"
$head = "Column`tColumn`tColumn"

En el primer ejemplo, la primera $ está siendo "escapado." Quita su significado especial como un descriptor de acceso variable. Si el equipo de $ contenía 'Servidor', a continuación, debug $ contendría "equipo $ contiene SERVER".

En el segundo ejemplo, ' t representa un carácter de tabulación horizontal, por lo que Windows PowerShell se colocará una tabulación entre cada columna. Puede leer acerca de otros caracteres de escape especiales en el shell about_escape_characters tema de ayuda.

Por último, utilice comillas dobles cuando una cadena debe contener comillas simples:

$filter1 = "name='BITS'"
$computer = 'BITS'
$filter2 = "name='$computer'"

En este ejemplo, la cadena literal es nombre = 'BITS'. Las comillas dobles contienen toda la cosa. Filter1 $ y $filter2 terminan que contiene exactamente lo mismo pero $filter2 se obtiene mediante el uso de la mano de sustitución de variable de comillas dobles. Tenga en cuenta que realmente importa sólo el conjunto más externo de comillas. No importan las comillas simples dentro de la cadena Windows PowerShell. Las comillas simples son caracteres literales sólo. Windows PowerShell no interpretarlos.

Las variables y los miembros del objeto

Todo el contenido de Windows PowerShell es un objeto. Incluso una simple cadena como "nombre" es un objeto, del tipo System.String. Puede canalizar cualquier objeto a Get-Member para ver su nombre de tipo (es decir, el tipo de objeto es) así como sus miembros, que incluye sus propiedades y métodos:

$var = 'Hello'
$var | Get-Member

Utilice un punto después de un nombre de variable para indicar el shell, "no deseo tener acceso a todo el objeto dentro de esta variable. Deseo obtener acceso a sólo uno de sus propiedades o métodos." Después del período, proporcione el nombre de propiedad o método.

Los nombres de métodos siempre van seguidos de un conjunto de paréntesis. Algunos métodos aceptan argumentos de entrada y los ir entre paréntesis en una lista separada por comas. Otros métodos no requieren ningún argumento y, por lo que los paréntesis están vacíos, pero no olvide los paréntesis:

$svc = Get-Service
$svc[0].
name
$name = $svc[1].
name
$name.length
$name.ToUpper()

Observe la línea de dos. Se inicia mediante el acceso al primer elemento de la variable $svc. El período medio, "no desea que todo el objeto. Sólo necesito un método o propiedad." Esto tiene acceso a sólo la propiedad name. Cinco de la línea muestra cómo tener acceso a un método, proporcionando su nombre después de un período, seguido de paréntesis.

Un período normalmente es un carácter no válido dentro de un nombre de variable, porque significa que el período que desea tener acceso a una propiedad o método. Eso significa que dos línea en el ejemplo siguiente no funcionará la forma en que se podría esperar:

$service = 'bits'
$name = "Service is $service.ToUpper()"
$upper = $name.ToUpper()
$name = "Service is $upper"

En la línea de dos, $nombre contendrá "servicio es de BITS.ToUpper()" Considerando que en la línea cuatro $nombre contendrá "Servicio es BITS".

Paréntesis

Aparte de su uso con métodos del objeto, entre paréntesis también actúan como un marcador de orden de ejecución para Windows PowerShell, al igual que en álgebra. En otras palabras, entre paréntesis indican la shell para "ejecutar este primer". Toda la expresión entre paréntesis se sustituye por lo que produce que la expresión. Aquí es SLO algunos ejemplos:

$name = (Get-Service)[0].
name
Get-Service -computerName (Get-Content names.txt)

En la línea uno, $nombre contendrá el nombre del primer servicio del sistema. Leyendo esto un poco de esfuerzo. Comience con la expresión entre paréntesis. Que es lo que Windows PowerShell comenzará con así. "Get-Service" se resuelve en una colección o matriz, de los servicios. [0] Tiene acceso al primer elemento de una matriz, por lo será el primer servicio. Porque es seguido de un punto, sabemos que estamos acceder a una propiedad o método de dicho servicio, en lugar de utilizar el objeto de todo el servicio. Por último, nos extraer sólo el nombre del servicio.

En línea de dos, la expresión entre paréntesis es leer el contenido de un archivo de texto. Suponiendo que el archivo contiene un nombre de equipo por línea, "Get-Content" "devolverá una matriz de nombres de equipo. Aquellos son apto para el parámetro – "computername" de "Get-Service". En este caso, el shell puede alimentar cualquier expresión entre paréntesis que devuelve una matriz de cadenas a la
parámetro – "computername", porque el parámetro está diseñado para aceptar las matrices de cadenas.

Ámbito

Ámbito es un concepto de programación que actúa como un sistema de contenedorización. Cosas como variables, alias, PSDrives y otros elementos de Windows PowerShell se almacenan en un ámbito. El shell mantiene una jerarquía de ámbitos y tiene un conjunto de reglas que determinan cómo ámbitos pueden interactuar y compartir información entre sí.

El comando de shell es un ámbito único, denominado el ámbito global. Cuando se ejecuta una secuencia de comandos, construye un nuevo ámbito y la secuencia de comandos se ejecuta dentro de ella. Cualquier cosa creada por la secuencia de comandos, como una nueva variable, se almacena en el ámbito de la secuencia de comandos. No es accesible por el shell de nivel superior.

Cuando finalice el script, se descarta su ámbito de aplicación y nada creado dentro de ese ámbito desaparece. Por ejemplo, crear una secuencia de comandos que contiene lo siguiente (no olvide no escriba los números de línea), y, a continuación, ejecuta esa secuencia de comandos desde la ventana de consola:

New-PSDrive -PSProvider FileSystem -Root C:\ -Name Sys
Dir SYS:

Después de ejecutar la secuencia de comandos, ejecute manualmente "Dir SYS:" y verá un error. Eso es porque el SYS: se creó la unidad en la secuencia de comandos. Una vez que se ha realizado la secuencia de comandos, no se ha descartado todo lo que creó. SYS: unidad ya no existe. No todo en el shell está en el ámbito. Elementos como los módulos se gestionan globalmente en todo momento. Una secuencia de comandos puede cargar un módulo y el módulo permanecerá cargado después de realiza la secuencia de comandos.

Si se trata de un ámbito tener acceso a algo que no se ha creado dentro de ese ámbito, Windows PowerShell espera el ámbito inmediatamente superior (el ámbito "principal"). Por eso el Dir alias trabajó en que la secuencia de comandos recién insertado. Aunque Dir no existía en el ámbito de la secuencia de comandos, existía en el ámbito inmediatamente superior: el ámbito global. Un ámbito es libre crear un elemento que tiene el mismo nombre que un elemento de un ámbito de nivel superior, aunque. Aquí es otra secuencia de comandos para probar:

Dir
New-Alias Dir Get-Alias
Dir

Que puede parecer extraño, pero la primera vez que ejecutó "Dir", no existía en el ámbito de la secuencia de comandos. Se utiliza el alias de Dir de nivel superior. Ese alias señala a Get-ChildItem, por lo que muestra una lista de directorios familiar.

A continuación, la secuencia de comandos crea un nuevo alias llamado Dir. Esto indica que el Alias de Get. Eso es lo que se ejecutó la segunda vez. Nada de esto afecta el alias Dir de nivel superior. Intente ejecutar Dir en el shell después de ejecutar la secuencia de comandos anterior, y aún obtendrá un listado de directorios.

Ámbito puede ser especialmente confuso cuando se trata de variables. Como regla general, un ámbito determinado nunca debe obtener acceso a elementos fuera de ámbito, especialmente las variables. Existe una sintaxis para hacerlo, como el uso de $global: var para acceder a la fuerza variable del ámbito global $var, pero que es una mala práctica salvo en circunstancias muy específicas.

Lenguaje de secuencias de comandos de Windows PowerShell

Windows PowerShell contiene un lenguaje de secuencias de comandos muy simplificado de menos de dos docenas de palabras. Que es una gran diferencia para un lenguaje de programación completo, como VBScript, que contiene casi 300 palabras clave.

El idioma de Windows PowerShell y simplificado aunque es posible, es más que suficiente para realizar el trabajo. Revisaré su construcción principales de secuencias de comandos ahora, aunque siempre puede obtener más ayuda sobre estas leyendo el correspondiente "tema dentro del shell acerca de". Por ejemplo, ayuda about_switchcontains información sobre la construcción de Switch, mientras que about_if de Ayuda contiene información sobre la si construir. Ejecute la ayuda acerca de * para obtener una lista de todos los "temas about".

Construir la si

Ésta es la construcción de toma de decisiones principal de Windows PowerShell. En su forma completa, ve así:

If ($this -eq $that) {
  # commands
} elseif ($those -ne $them) {
  # commands
} elseif ($we -gt $they) {
  # commands
} else {
  # commands
}

La palabra clave "If" es una parte obligatoria de esta construcción. Una expresión entre paréntesis siguiente que se debe evaluar Verdadero o falso. Windows PowerShell siempre se interpretarán cero como False y cualquier valor distinto de cero como True.

Windows PowerShell también reconoce las variables integradas $True y False $ que representa los valores booleanos. Si la expresión entre paréntesis funciona en True, se ejecutarán los comandos en el siguiente conjunto de llaves. Si la expresión es False, no ejecutan los comandos. Y eso es todo lo que necesita para un válido si construir.

Puede ir un poco más lejos al proporcionar una o varias secciones de "ElseIf". Estos trabajos de la misma manera que si construir. Obtienen su propia expresión entre paréntesis. Si es True, se ejecutarán los comandos dentro de la siguiente figura entre llaves. Si no es así, ellos no harán.

Puede envolver con un bloque Else, que se ejecutará si ninguno de los bloques anteriores ejecutar. Se ejecutará sólo el bloque asociado con la primera expresión es True. Por ejemplo, si $esto no igual a $, y $ no los igual $ ejecutan a ellos, a continuación, los comandos de línea de cuatro y nada más. Windows PowerShell incluso no evalúa la segunda expresión elseif en línea cinco.

El carácter # es un carácter de comentario, haciendo Windows PowerShell esencialmente omitir cualquier cosa desde allí hasta un carro retorno. Observe también la atención con el que se formatearon las construcciones mencionadas. También puede ver así el formato de algunos amigos:

No importa dónde coloque las llaves. Sin embargo, lo que importa es que usted sea coherente en su ubicación para que las secuencias de comandos son más fáciles de leer. También es importante aplicar una sangría, en el mismo nivel, todas las líneas dentro de las llaves.

El ISE Windows PowerShell le permite utilizar la tecla Tab para tal fin, y el valor predeterminado es una sangría de cuatro caracteres. El código de aplicación de sangría es una práctica recomendada de núcleo. Si no lo hace, tendrá un tiempo duro correctamente coincidentes de apertura y cierre entre llaves en secuencias de comandos complejas. Además, todos los otros niños Windows PowerShell hará diversión de usted. Tenga en cuenta esta secuencia de comandos deficientes:

function mine {
if ($this -eq $that){
get-service
}}

Que es mucho más difícil de leer, depurar, solucionar problemas y mantener. Mientras que el espacio después del paréntesis de cierre no es necesario, hacen más fácil de leer la secuencia de comandos. El código con sangría no es necesario, pero facilita la siga la secuencia de comandos. Tenga en cuenta esto en su lugar:

function mine {
 if ($this -eq $that){
  get-service
 }
}

Colocar una llave de cierre único en una línea por sí solo no sea necesario para el shell, pero se aprecia por el ojo humano. Ser un formateador ordenado y tendrá menos problemas en las secuencias de comandos.

La mientras que la construcción

Se trata de una construcción de bucle en Windows PowerShell. Se ha diseñado para repetir un bloque de comandos como alguna condición es True o hasta que una condición sea True. Aquí es el uso básico:

Do {
  # commands
} While ($this -eq $that)

En esta variante de la construcción, los comandos dentro de las llaves siempre se ejecutarán al menos una vez. While condición no se evalúa hasta después de la primera ejecución. Puede mover el tiempo, en cuyo caso los comandos se ejecutarán sólo si la condición es True, en primer lugar:

While (Test-Path $path) {
  # commands
}

Observe el segundo ejemplo no utiliza un operador de comparación como - EC. Eso es porque se pasa el cmdlet Test-Path devolver verdadero o falso para comenzar. No hay comparar en True o False para que funcione la expresión.

La expresión entre paréntesis que se utiliza con estas construcciones de secuencias de comandos simplemente necesita simplificar a True o False. Si está utilizando un comando como ruta de acceso de prueba, que siempre devuelve True o False, que es todo lo que necesita. Como siempre, hay un tema "acerca de" en el shell que muestra otras formas de utilizar esta construcción.

La construcción de ForEach

Esta construcción es similar en funcionamiento para el cmdlet ForEach-Object. Se diferencia sólo en su sintaxis. El propósito de ForEach es tomar una matriz (o una colección, que en Windows PowerShell es el mismo que una matriz) y enumerar los objetos de la matriz para poder trabajar con uno en uno:

$services = Get-Service
ForEach ($service in $services) {
  $service.Stop()
}

Es fácil para los recién llegados a overthink esta construcción. Tenga en cuenta que la palabra inglesa plural "servicios" no significa nada a Windows PowerShell. Este nombre de variable se utiliza para recordar que contiene uno o más servicios. Simplemente porque es plural no tiene el shell se comportan de manera especial.

La palabra clave "in" en línea dos forma parte de la sintaxis de ForEach. La variable $service está compuesta por. Podría haber sido fácilmente $fred o $café y habría funcionado en la misma manera.

Windows PowerShell se repetirá los comandos de la construcción: los contenidos dentro de llaves: una vez para cada objeto de la segunda variable (servicios$). Cada vez, tomará un solo objeto de la segunda variable (servicios$) y colóquelo en la primera variable (servicio$).

En esta construcción, utilice la primera variable (servicio$) para trabajar con un objeto individual. En la línea de tres, el punto indica que "no se desea trabajar con todo el objeto, sólo uno de sus miembros, el método Stop."

Hay ocasiones cuando usar ForEach es inevitable y conveniente. Sin embargo, si tiene un poco de programación o secuencias de comandos de experiencia, a veces puede saltar mediante ForEach cuando no es el mejor enfoque. El ejemplo anterior no es una buena razón para utilizar ForEach. Esto sería más fácil:

Get-Service | Stop-Service

El punto aquí consiste en evaluar el uso de ForEach. Asegúrese de que es la única manera de realizar la tarea en cuestión. Aquí hay algunos casos donde ForEach es probablemente la única manera de ir:

  • Cuando se necesitan ejecutar un método contra un montón de objetos y hay un cmdlet que realiza la acción equivalente.
  • Cuando tiene un montón de objetos y necesita realizar varias acciones consecutivas contra cada uno.
  • Cuando tiene una acción que sólo se puede realizar con un objeto a la vez, pero la secuencia de comandos puede estar trabajando con uno o varios objetos, y no tiene forma de saber de antemano.

El resto de construcciones

Windows PowerShell tiene varias otras construcciones de secuencias de comandos, incluidos el conmutador, para y así sucesivamente. Éstos están documentados en "acerca de" temas de Ayuda de la shell. A veces, puede utilizar las construcciones que se trata en este documento para reemplazar los otros constructores. Por ejemplo, puede reemplazar el Switch con un If construcción que utiliza varias secciones ElseIf. Puede reemplazar para con la instrucción ForEach, o incluso con el cmdlet ForEach-Object. Por ejemplo, con un bucle que se ejecuta exactamente 10 veces:

1..10 | ForEach-Object -process {
  # code here will repeat 10 times
  # use $_ to access the current iteration
  # number
}

Es seleccionar la mejor construcción para realizar el trabajo. Si estás explorando Internet para las secuencias de comandos, estar preparado para ejecutarse a través de las variaciones todas.

Funciones

Una función es un tipo especial de construcción que se utiliza para contener un grupo de comandos relacionados que realizan una tarea sencilla y específica. En términos generales, puede tomar cualquier secuencia de comandos Windows PowerShell y "wrap" dentro de una función:

function Mine {
  Get-Service
  Get-Process
}
Mine

Esto define una función nueva llamada "Míos". Básicamente que convierte los míos, en un comando, lo que significa que puede ejecutar la función simplemente escribiendo su nombre. Eso es lo que cinco hace de la línea. Se ejecuta la función.

Las funciones normalmente están contenidas dentro de un archivo de secuencia de comandos. Una sola secuencia de comandos puede contener varias funciones. Las funciones pueden incluso contener otras funciones.

Sin embargo, las funciones son elementos con ámbito. Esto significa que sólo puede utilizar una función dentro del mismo ámbito en el que se creó. Si coloca una función en una secuencia de comandos y, a continuación, ejecute esa secuencia de comandos, la función sólo estará disponible dentro de la secuencia de comandos y sólo para la duración de la secuencia de comandos. Cuando termina la secuencia de comandos de ejecución de la función, todo lo demás como en el ámbito de la secuencia de comandos: desaparece. Aquí es un ejemplo:

function One {
  function Two {
Dir
  }
  Two
}
One
Two

Supongamos que anotarlo en un solo archivo de comandos y ejecuta esa secuencia de comandos. Línea siete ejecuta la función de uno, que se inicia en la línea uno. Línea cinco ejecuta una función denominada Two, que comienza en la línea de dos. Por lo que el resultado será un listado de directorios, que se encuentra en línea tres dentro de la función dos.

Sin embargo, la línea siguiente para ejecutar será línea ocho, y que se producirá un error. La secuencia de comandos no contiene una función denominada dos. Función dos está enterrado en función de uno. Como resultado, que existe dentro de un ámbito del función. Pueden ver sólo otras cosas dentro de una función de dos. Intentando llamar a dos desde otro lugar, se producirá un error.

Adición de parámetros a una secuencia de comandos

No es habitual para crear una secuencia de comandos que se va a hacer exactamente lo mismo cada vez que se ejecuta. Con más frecuencia, tendrá las secuencias de comandos que contengan algún tipo de datos de la variable o el comportamiento de las variables. Puede dar cabida a estas variaciones con parámetros.

Los parámetros se definen de forma especial en la parte superior de la secuencia de comandos. Puede preceder a esta definición con comentarios, pero debe ser de lo contrario las líneas de código dentro de la secuencia de comandos ejecutables. Dentro del área de definición de parámetro, cada parámetro se separa del siguiente por una coma. En consonancia con la idea de formato ordenado, ayuda a colocar cada parámetro en una línea propia. A continuación se muestra un ejemplo:

param (
  [string]$computername,
  [string]$logfile,
  [int]$attemptcount = 5
)

Este ejemplo define tres parámetros. Dentro de la secuencia de comandos, simplemente se utilizan como cualquier otra variable. Observará que en la línea de cuatro, he asignado un valor predeterminado para el parámetro de attemptcount $. El valor predeterminado será reemplazado por cualquier parámetro de entrada, pero se utilizará si la secuencia de comandos se ejecuta sin ese parámetro especificado.

Aquí hay varias maneras en que la secuencia de comandos puede ejecutarse, suponiendo que guardarlo como Test.ps1:

./test -computername SERVER
./test -comp SERVER -log err.txt -attempt 2
./test SERVER err.txt 2
./test SERVER 2
./test -log err.txt -attempt 2 -comp SERVER

La secuencia de comandos acepta parámetros de una forma muy parecida cualquier cmdlet. Los nombres de variables se utilizan como los nombres de parámetro especificados con el guión habitual que precede a todos los nombres de parámetro en Windows PowerShell. Éste es un desglose de cómo funciona:

  • En la línea uno, voy a sólo especificar uno de los parámetros:$ logfile, por tanto, estará vacía y $attemptcount contendrá 5, su valor predeterminado.
  • En la línea de dos, voy a especificar los tres parámetros, aunque estoy haciendo para que usando acortó los nombres de parámetro. Al igual que con los cmdlets, sólo necesita escribir suficiente del nombre del parámetro Windows PowerShell saber lo que se está hablando.
  • Línea de tres me muestra nuevamente todos los tres parámetros, aunque lo hago por posición, sin necesidad de utilizar nombres de parámetro. Como recuerdo proporcionar los valores en el orden exacto en que se enumeran los parámetros en la secuencia de comandos, esto funcionará sin problemas.
  • Línea cuatro muestra ¿qué sucede si no se tiene cuidado. Aquí, $NombreDeEquipo contendrá 'Servidor' y $logfile contendrá 2, mientras que va a contener $attemptcount 5. Probablemente no es lo intentaba. Cuando no utilice nombres de parámetro, es más difícil ser flexibles. También es más difícil que alguien lo que significa, lo que hace más difícil solucionar los problemas de descodificación.
  • Cinco de la línea es un ejemplo mejor. Aquí, he especificado en el orden de parámetros, pero que está bien debido a que los nombres de parámetro de uso. Como norma general, siempre utilice nombres de parámetro para el mayor grado de flexibilidad. No necesito recordar el orden en que llegaron.

Secuencias de comandos avanzadas

Windows PowerShell admite una técnica para especificar información adicional acerca de los parámetros. Esto le permite declarar un parámetro como obligatorios, aceptando la entrada de la canalización y así sucesivamente. Esta técnica se denomina enlace de Cmdlet.

No cambia la forma en que la secuencia de comandos utiliza parámetros. Simplemente proporciona el shell un poco más información acerca de los parámetros. Encontrará esta técnica utilizada más habitualmente en una función, pero la sintaxis es válida dentro de una secuencia de comandos. A continuación se muestra un sencillo ejemplo:

[CmdletBinding()]
param (
  [Parameter(Mandatory=$True)]
  [string]$computername,

  [Parameter(Mandatory=$True)]
  [string]$logfile,

  [int]$attemptcount = 5
)

Lo he agregado fue la instrucción [CmdletBinding()] como la primera línea ejecutable de código dentro de la secuencia de comandos. Es correcto para los comentarios que preceda a esto, pero nada más. También agregué una instrucción [Parameter()] a dos de Mis parámetros. Dentro de esa instrucción [Paramater()], he indicado que estos parámetros son obligatorios. Ahora, si alguien intenta ejecutar la secuencia de comandos sin especificar estos parámetros, Windows PowerShell les pedirá la información.

Observe que el último parámetro no tiene las instrucciones especiales y los tres parámetros todavía aparecen en una lista separada por comas (es decir, los dos primeros parámetros son seguidos por comas). Hay un montón de otras instrucciones que se pueden especificar para un parámetro, que puede leer acerca de la about_functions_advanced_parameters tema de ayuda.

Se trata de una revisión de torbellino de algunos conceptos clave de Windows PowerShell relacionados con las secuencias de comandos. Espero que ha aprendido una o dos cosas. Ser capaz de generar secuencias de comandos parametrizadas es especialmente útil, porque puede hacer que las secuencias de comandos con el aspecto y comportan como cmdlets nativos de Windows PowerShell.

Don Jones

Don Jones es un premio MVP de Microsoft y el destinatario de "Aprender Windows PowerShell en un mes de comidas" (Manning Publications, 2011), un libro diseñado para ayudar a cualquier administrador serán efectivos con Windows PowerShell. Jones también ofrece formación de Windows PowerShell pública y a domicilio. Póngase en contacto con él a través de su sitio Web en ConcentratedTech.com.

Contenido relacionado