PowerShell

PowerShell ofrece un entorno de ejecución de comandos....

Si PowerShell no se ejecuta con elevación, algunos comandos pueden ser denegados por falta de privilegios. Para iniciar PowerShell con elevación, hacemos clic derecho sobre el icono de PowerShell y elegimos "Ejecutar como Administrador".

Cmdlets

PS soporta los comandos de MSDOS, pero añade un nuevo tipo de comandos: CMDLETS. Los cmdlets se componen de dos partes:

  • Un verbo: get, set, add, remove, start, stop, etc.
  • Un pronombre: process, service, netadpater, etc.

De este modo, un posible cmdlet podría ser get-service o bien stop-process.

Para conocer los verbos destacados, utilizar el comando get-verb

Para conocer cmdlets a partir de un indicio, podemos utilizar el comando get-command, combinado con el inidicio que buscamos:

PS C:\Users\Administrator\> get-command -name start*

El verbo GET

Get es el verbo más común. El 25% de comandos en PowerShell utilizan este verbo. Algunos comandos interesantes son:

  • get-process
  • get-hotfix
  • get-service
  • get-netadapter
  • get-netconnectionprofile
  • get-culture
  • get-date
  • get-random
  • Autocompletado

    Podemos utilizar el autocompletado para completar nombres de cmdlets, parámetros, etc. Por ejemplo si escribimos Get-Hot y pulsamos el tablulador, se autocompleta a Get-Hotfix. Si después escribimos un espacio y un signo "-" y tabulamos, podremos ver las diferentes opciones.

    Obtener ayuda de un comando

    Para obtener ayuda de un cmdlet, podemos ejecutar el comando get-help. Por ejemplo, para saber cómo usar el comando get-hotfix:

    get-help get-hotfix

    Además existen varias opciones, que podemos añadir a get-help

    Actividad 1. Busca información sobre get-help, para averiguar como obtener información sobre los parámetros del comando get-hotfix.

    Ejecuta el comando necesario, y toma una captura de su resultado, donde se pueda ver el comando ejecutado. Guarda la captura con el nombre Act1-powershell.png.

    Parámetros comunes

    Todos los cmdlets soportan ciertos parámetros comunes. Estos parámetros son los siguientes:

    • Verbose
    • Debug
    • WarningAction
    • ErrorAction
    • ErrorAction
    • ErrorVariable
    • OutBuffer

    Además, si un cmdlet cambia el estado del sistema (como por ejemplo detener un proceso, o iniciar un servicio), entonces hay dos parámetros adicionales:

    • WhatIf
    • Confirm

    Para obtener información sobre estos parámetros, podemos utilizar el comando get-help about_commonparameters

    Verbose

    Si un comando no muestra resultado, y queremos saber más sobre lo que está pasando, podemos utilizar el parámetro verbose. Por ejemplo, vamos a abrir un par de "bloc de notas". Después, si ejecutamos el comando el comando stop-process -name notepad, veremos que no hay salida.

    Volvamos a abrir un par de "bloc de notas" y en este caso ejecutemos el comando stop-process -name notepad -verbose, y en este caso obtendremos una salida más detallada.

    PS C:\> Stop-Process -Name notepad -Verbose VERBOSE: Performing operation "Stop-Process" on Target "notepad (5564)". VERBOSE: Performing operation "Stop-Process" on Target "notepad (5924)". PS C:\>

    ErrorAction

    Si lo que queremos es ocultar errores, podemos usar el parámetro ErrorAction con el valor SilentlyContinue. Por ejemplo, si ejecutamos get-process notepad, sin que exista dicho proceso ejecución, se mostrará un error. En cambio, si ejecutamos el comando get-process notepad -erroraction silentlycontinue, no nos mostrará errores, simplemente una salida vacía.

    Para no tener que escribir tanto, podemos usar la siguiente combinación de caracteres: get-pro<tab> -n<tab> notepad -e<tab> s<tab>

    Registro de la sesión de PowerShell

    PowerShell permite registrar lo que se hace en cada sesión mediante el comando Start-Transcript. Una vez que se ejecuta este cmdlet, todos los comandos, salidas, mensajes de error, etc. van apareciendo en el archivo de transcripción.

    Actividad 2. Inicia la transcripción de PowerShell. Después ejecuta un par de comandos y comprueba que el archivo de transcripción está registrando lo que haces.

    Abre el contenido del archivo de transcripción con notepad y toma una captura. Guárdala con el nombre Act2-powershell.png

    Para detener la transcripción ejecutamos el comando stop-transcript.

    Consultar temas de PowerShell

    El cmdlet get-help devuelve información sobre dos tipos de temas:

    • descripciones de cmdlets: incluye información sobre la función del comando, sintaxis, parámetros y ejemplos.
    • temas conceptuales: incluyen información de ayuda sobre PowerShell, pero no sobre un comando concreto.

    Para obtener ayuda conceptual sobre algún tema, el comando empezará del siguiente modo: get-help about_. De hecho, si queremos conocer los temas conceptuales disponibles, podemos usar el siguiente comando get-help about_<tab>

    Actividad 3. Busca información sobre las sentencias de control If, empleando para ello la ayuda de temas conceptuales.

    Una vez que localices la documentación de ayuda, toma una captura y guáradala con el nombre Act3-powershell.png

    Prueba con los siguientes comandos:

    • get-verb
    • get-command -verb get
    • get-command -verb get -noun *tcp*

    Afinar las búsquedas de cmdlets

    Si ejecutaste los comandos anteriores, verás que a cada cmdlet le corresponde un módulo (ModuleName). Podemos afinar nuestras búsquedas del cmdlet apropiado, utilizando el módulo como información adicional. Por ejemplo, vamos a ver algunos comandos de ejemplo:

    Get-Command -Verb get -Noun *ip* -Module NetTcpIp Get-Command -Module NetTCPIP -Verb set

    De este modo, y gracias a la claridad de los nombres de los cmdlets, podemos fácilmente conocer el cmdlet que necesitamos para una cierta tarea.

    Actividad 4. Muestra mediante un cmdlet la tabla de rutas del sistema.

    Ejecuta el cmdlet que necesites y toma una captura con el nombre Act4-powershell.png

    Show-command

    El comando show-command muestra una interfaz gráfica de entrada para el comando. Por ejemplo, show-command -name get-process.

    Directiva de ejecución de scripts

    Por defecto, PowerShell desactiva la ejecución de scripts por defecto. Para permitir la ejecución de comandos en el sistema local, podemos ejecutar el comando siguiente: Set-ExecutionPolicy -Scope LocalMachine -ExecutionPolicy unrestricted.

    Tuberías

    Podemos pasar el resultado de un comando a otro comando. Por ejemplo, vamos a ejecutar el comando Get-Process. El resultado incluye propiedades como NPM (cantidad de memoria no paginada), PM (cantidad de memoria paginada en uso) o VM (cantidad de memoria virtual usada). Si queremos ordenar por VM, por ejemplo, usaremos el comando: Get-Process | Sort-Object -Property VM -Descending. El parámetro Property se usa por defecto con el cmdlet sort. Así, que el comando anterior puede ser ejecutado como Get-Process | sort vm -descending. Además se pueden utilizar varias propiedades como criterios de ordenación, separados por ",". Por ejemplo: Get-Process | sort vm, cpu

    ¿Qué hará el comando Get-Service | sort status?

    Agrupaciones

    Se pueden agrupar los resultados de comandos en base a un criterio. Por ejemplo, el comando Get-Service | Sort-Object status | Group-Object -Property status agrupará los servicios según su estado. Una vez más, el parámetro -Property es tomado por defecto, es decir, que se puede ejecutar del siguiente modo: Get-Service | Sort-Object status | Group-Object status. El objetivo de la agrupación, es hacer recuento.

    ¿Qué hará el siguiente comando?

    Get-Process | sort name | group name | sort count -Descending

    Filtrado de comandos

    PowerShell está orientada a objetos, a diferencia de bash, por ejemplo, que está orientada a texto. Por ello, cada propiedad de una salida se puede manejar directamente como un dato independiente del resto. Con el cmdlet Where-Object podemos filtrar los resultados según algún criterio. Por ejemplo, observa los siguientes comandos:

    Get-WindowsDriver -Online Get-WindowsDriver -Online | where date -gt 10/8/2014 Get-HotFix Get-HotFix | where installedon -gt 10/1/12 Get-Process Get-Process | where CPU -gt 10

    Existen distintas comparaciones que podemos hacer, como las siguientes:

    • -eq - Igual a. Por ejemplo, where entrytype -eq 'error'
    • -le - Menor o igual a.
    • -lt - Menor que.
    • -gt - Mayor que.
    • -ge - Mayor o igual que.
    • -eq - Igual a.
    • -match - Comparación con una expresión regular. Por ejemplo, Get-Process | where ProcessName -Match 'host'

    Actividad 5. Ejecuta un comando que obtenga únicamente la dirección IPv4 de la interfaz de red conectada a la red del aula. Para ello, combina los siguientes elementos mediante tuberías:

    • El cmdlet get-netipaddress
    • El cmdlet select-object
    • El cmdlet where-object para discriminar la dirección IPv4 de la dirección IPv6.

    NOTA: La expresión que permite discriminar una dirección IPv6 de una IPv4 es "*.*.*.*"

    Ejecuta el comando y toma una captura con el resultado. Guárdala con el nombre Act5-powershell.png.

    Formateando la salida

    Tablas

    Muchos comandos tienen salidas con más información de la necesaria. El cmdlet permite consultar los nombres de los parámetros de salida del cmdlet get-process:

    get-process | get-member get-process | get-member -MemberType alias*

    El comando Get-Member -MemberType alias* puede tener interés, puesto que muestra solo un subconjunto de propiedades, que pueden ser suficientes para nuestros propósitos.

    Así podemos conocer los parámetros de cualquier cmdlet. A partir de esta información podemos consultar y tabular la información quen nos interese. Por ejemplo:

    Get-Process | Format-Table -Property name, handles, mv, ws

    Actividad 6. Muestra una tabla por pantalla que muestre la siguiente información:

    • El nombre de cada interfaz de red.
    • La dirección IPv4 de dicha interfaz.

    El cmdlet Format-Table adminte dos parámetros interesantes: -AutoSize y -wrap. Prueba a ejecutar los siguientes comandos:

    get-hotfix | format-table -property pscomputername, description, hotfixid, fixcomments, csname, caption, installdate, installedby get-hotfix | format-table -property pscomputername, description, hotfixid, fixcomments, csname, caption, installdate, installedby -autosize get-hotfix | format-table -property pscomputername, description, hotfixid, fixcomments, csname, caption, installdate, installedby -autosize -wrap get-hotfix | format-table -property pscomputername, description, hotfixid, fixcomments, csname, caption, installdate, installedby -wrap

    Listas

    En casos donde estamos mostrando demasiadas propiedades para que se vean bien en una tabla, puede ser interesante usar listas. Prueba el ejemplo anterior, empleando el cmdlet Format-List en lugar de Format-Table:

    get-hotfix | format-list -property pscomputername, description, hotfixid, fixcomments, csname, caption, installdate, installedby

    Comodines

    Podemos utilizar comodines para la selección de propiedaes. Por ejemplo:

    Get-EventLog application -newest 5 Get-EventLog application -newest 5 | Format-List so*,e*

    Vista amplia

    Para mostrar una sola propiedad, puede interesar el uso de varias columnas, de modo que no tengamos una lista de una sola columna que se salga de la pantalla. El cmdlet Format-Wide permite mostrar la información en este sentido. Prueba los siguientes comandos:

    Get-Service | select name Get-Service | Format-Wide -Property name Get-Service | Format-Wide -Property name -AutoSize Get-Service | Format-Wide -Property name -Column 5

    GridView

    Para terminar, también se pueden ver los resultados empleando el cmdlet out-gridview

    Actividad 7. Obtén una lista de servicios y muéstralos emplenado out-gridview. Indaga sobre como utilizar este formato.

    Una vez obtengas la vista, toma una captura y guárdala con el nombre Act7-powershell.png

    Almacenar la salida

    La salida de un comando se puede almacenar en un archivo de texto, en un archivo .csv (editable desde un hoja de cálculo) o bien en formato xml. Por ejemplo:

    Get-Service | Format-Table -Property * -Force -Auto | Out-File -FilePath c:\psout\Servicios.txt -Encoding UTF8 -Width 500 Get-Process | Export-Csv -Path c:\psout\process.csv Get-Process | Export-Csv -Path c:\psout\process.csv -NoTypeInformation Get-Process | Export-Clixml -Path c:\psout\processXML.xml

    Importar los datos

    Los datos exportados a .csv y .xml pueden importarse desde PowerShell para ser procesados.

    El parámetro -NoTypeInformation permite eliminar el tipo de información almacenado en el archivo .csv. Esta opción es conveniente cuando la información vaya a ser importada en una hoja de cálculo, o bien desde SQL. Sin embargo, dicha opción es conveniente cuando el contenido del archivo .csv se vaya a utilizar desde PowerShell tras importarla. Por ejemplo:

    get-process | Export-Csv -Path c:\psout\processInfo.csv Import-Csv -Path C:\psout\processInfo.csv | sort vm | select -First 2 | format-table name, vm

    El problema de los datos complejos.

    El formato XML tiene una ventaja sobre .txt y .csv. Permite almacenar información compleja, que incluya datos no lineales. Por ejemplo, un proceso puede estar utilizando más de un hilo de ejecución. Podemos verlo mediante el comando get-process | format-list name,threads. Ahora, si exportamos el resultado a un archivo .csv, y luego desde powershel tratamos de hacer uso de dicha información, tenemos el siguiente problema:

    get-process | export-csv -path c:\psout\processinfo.csv $csv = import-csv -path c:\psout\processinfo.csv $csv[0].threads

    El resultado que obtenemos es System.Diagnostics.ProcessThreadCollection, que es el contenedor donde están los hilos de ejecución. Sin embargo, este problema no se da con XML:

    get-process | export-clixml -path c:\psout\processinfo.xml $xml = import-clixml -path c:\psout\processinfo.xml $xml[0].threads

    El resultado obtenido sí es el esperado. Compruébalo.

    Proveedores de PowerShell

    PowerShell unifica el acceso a los diferentes tipos de datos de Windows a través de los mismos cmdlets. Es decir, el mismo cmdlet Get o Set sirve para acceder y modificar información del sistema de archivos, el entorno o el registro, Active Directory o SQL Server, en lugar usar un comando diferente para cada cosa. Y esto lo consigue a través de los proveedores de PowerShell.

    Para poder saber cuáles son los proveedores disponibles, podemos ejecutar el cmdlet Get-PSProvider.

    El proveedor de Alias

    Un alias es un atajo para un cmdlet. Los alias ya están presentes por defecto en PowerShell, pero ademas es customizable, para poder crear nuestro propios alias.

    No es una buena práctica compartir scripts de PowerShell con alias personalizados, ya que sólo existen en nuestro sistema.

    Para establecer un nuevo alias indicamos en primer lugar que vamos a trabajar en la unidad Alias:\, donde PowerShell almacena los alias, mediante el comando Set-Location alias:. Después utilizaremos los cmdlets Get-Item, Set-Item, New-Item o Remove-Item según lo que queramos hacer. Por ejemplo, para establecer el alias procesos para el cmdlet Get-Process:

    PS C:\> Set-Location alias: PS Alias:\> New-Item -Name procesos -Value Get-Process

    Ahora podemos ejecutar el alias procesos en lugar de Get-Process.

    Si ejecutamos en la unidad alias: el comando dir (o bien Get-Item *) podemos ver todos los alias existentes. Si quisiéramos ahora borrar el alias creado anteriormente, bastaría ejecutar Remove-Item procesos

    Si no nos encontramos en la unidad alias: podemos borrar el alias mediante el comando RemoveItem Alias:\procesos

    Una vez que cerremos la sesión, los alias añadidos se perderán. Para hacerlos persistentes, podemos añadir un script profile.ps1 en C:\Windows\System32\WindowsPowerShell\v1.0 con el siguiente contenido:

    new-alias -name procesos -value get-process

    El proveedor de entorno

    Desde el provedor de entorno podemos acceder a las variables de entorno del sistema. Una variable de entorno es, por ejemplo %windir%. Vamos a probar los siguientes comandos:

    cmd echo %windir% exit

    Obtenemos C:\WINDOWS.

    Para poder acceder a las variables de entorno, debemos ir la unidad env:, mediante el comando Set-Location env:. Para comprobar las variables de entorno disponibles, ejecutamos el comando Get-Item *.

    Si queremos obtener el valor de una variable de entorno, podemos probar las siguientes opciones:

    Set-Location env: Get-Item windir
    (Get-Item env:windir).value
    get-item env:windir | select value
    $env:windir

    Actividad 8. Añade una nueva variable de entorno, llamada rutausuarios con el valor C:\Users. Después comprueba que está disponible, consultando su valor. Finalmente elimínala

    Comprueba el valor de la variable de entorno rutausuarios, y después elimínala. Toma una captura con el nombre Act8-powershell.png

    El proveedor del sistema de archivos

    Este proveedor permite hacer lo que ya se puede hacer mediante comandos de CMD, pero utilizando cmdlets. A continuación se presentan algunos ejemplos:

    New-Item -Path C:\carpetaejemplo -ItemType directory Set-Location C:\carpetaejemplo New-Item -Name archivoejemplo.txt -ItemType file Add-Content -Path .\archivoejemplo.txt -Value "Este es contenido nuevo" Get-Content -Path .\archivoejemplo.txt

    El proveedor del registro

    El proveedor del registro permite trabajar con el registro de Windows. Por defecto se crean dos unidades, HKCU y HKLM:

    Get-PSDrive -PSProvider registry

    Además de estas dos unidades, podemos crear otras nuevas. Por ejemplo, si quisiéramos crear una nueva unidad para la clave HKEY_CLASSES_ROOT, podríamos ejecutar el comando siguiente:

    New-PSDrive -PSProvider registry -Root HKEY_CLASSES_ROOT -Name HKCR

    Una vez creada la unidad, podemos acceder a ella a través del comando Set-Location, y conocer todas las entradas del registro con el comando get-item *.

    Para consultar sobre la clave "HKCR\.ps1", podemos hacer lo siguiente:

    Set-Location HKCR: Get-Item .\.ps1 | format-list *

    Supongamos que estamos consultando la clave del registro HKCU\Control Panel\Desktop\colors y queremos obtener información sobre la entrada Window. Entonces haremos lo siguiente:

    Set-Location "HKCU:\Control Panel\Desktop" Get-Item colors (Get-ItemProperty colors).Window

    Crear una nueva clave de registro, es similar a crear un nuevo archivo o una nueva carpeta empleando el cmdlet New-Item. Además, podemos usar el cmdlet Test-Path para comprobar si ya existe. Por ejemplo:

    Set-Location HKCU: Test-Path .\Software\sample New-Item -Path .\Software -Name ejemplo

    Para asignar un valor a la entrada por defecto de la clave:

    Set-Item -Path HKCU:\Software\ejemplo -Value "entrada ejemplo"

    Para crear una nueva entrada de tipo DWORD, por ejemplo:

    New-ItemProperty -Path HKCU:\Software\ejemplo -Name entradaejemplo -Value 12 -PropertyType "DWord"

    Para modificar el valor de una entrada del registro:

    Set-Location HKCU: Set-ItemProperty -Path HKCU:\Software\ejemplo -Value "Nuevo valor" -name entradaejemplo

    Para consultar las entradas dentro de una cierta clave:

    Get-ItemProperty -Path HKCU:\Software\ejemplo

    Actividad 9. Repite la actividad 6 del tema del registro, pero en este caso emplenando los cmdlets de PowerShell.

    Una vez completado el ejercicio, consulta el contenido de la clave Run desde PowerShell, y toma una captura. Llámala Act9-powershell.png

    PowerShell scripts

    La principal razón para utilizar scripts, es la reutilización de código y su automatización. Para crear un script, basta con copiar el comando a un archivo de texto y guardarlo empleando la extensión .PS1. Para ejecutuarlo, se puede arrastrar el archivo a la consola de PowerShell, o bien escribir la ruta al mismo.

    Activar la ejecución de scripts

    Por defecto está desactivada la ejecución de scripts en PowerShell. Se puede activar la ejecución de scripts desde una directiva de grupo en un dominio, o bien en el mismo servidor empleado el cmdlet ExecutionPolicy. Existen varios niveles de activación:

    • Restricted - No ejecuta scripts (es la opción por defecto).
    • AllSigned - Requiere que todos los scripts estén firmados.
    • RemoteSigned - Requiere que todos los scripts y archivos de configuración descargados de Internet estén firmados.
    • Urestricted - Pregunta antes de ejecutar un script sin firmar.
    • Bypass - No bloquea ningún script.
    • Undefined - Borra la directiva de ejecución del ámbito de directiva de ejecución actual.

    Además hay tres ámbitos de directiva de ejecución:

    • Process - La directiva de ejecución solamente afecta al proceso actual de PowerShell.
    • CurrentUser - La directiva de ejecución afecta solo al usuario actual.
    • LocalMachine - La directiva de ejecución afecta a todos los usuarios del sistema.

    Establecer la directiva de ejecución requiere permisos de administrador en la máquina local. Un usuario sin permisos de administración puede establecer la directiva de ejecución de scripts para el ámbito CurrentUser. La recomendación es utilizar el nivel "RemoteSigned". Para poder ver la directiva de ejecución para todos los ámbitos, podemos utilizar el siguiente comando:

    Get-ExecutionPolicy -List

    Para establecer una directiva de ejecución, podemos utilizar el cmdlet Set-ExecutionPolicy, combinando los parámetros -ExecutionPolicy y -Scope.

    Actividad 10. Cambia la directiva de ejecución para permitir la ejecución de scripts locales en la máquina local. Después comprueba que la configuración de la directiva es la correcta.

    Ejecuta el comando para cambiar la directiva, y después consulta, con el comando Get-ExecutionPolicy, el estado de la directiva. Toma una captura y guárdala con el nombre Act10-powershell.png

    Creando un script

    Vamos a crear una carpeta llamada C:\scripts\ y dentro vamos a crear un archivo llamado Procesos.ps1, con el contenido siguiente:

    Get-Process

    Ahora vamos a crear otro script llamado pararadobe.ps1 con el contenido siguiente:

    get-process adoberdr | stop-process

    Al ejecutarlo obtenemos un error. Si no queremos que se muestren los errores, podemos añadir el parámetro -erroraction silentlycontinue, quedando el script como sigue:

    get-process -name adoberdr -erroraction silentlycontinue | stop-process

    Paso de objetos a través de las tuberías

    En ocasiones un cmdlet consume el objeto que se le pasa por una tubería, como es el caso de Stop-Process, y no devuelve nada. Sin embargo, podemos estar interesados en pasar el objeto consumido al siguiente comando a través de una tubería. Para hacer esto, utilizamos el parámetro -PassThru. Vamos a observar el siguiente comando:

    $proceso = "notepad" Get-Process -name $proceso -erroraction silentlycontinue | Stop-Process -passthru | ForEach-Object { $_.name + ' con ID: ' + $_.ID + ' ha sido detenido.'}

    Analicemos el tercer comando:

    • ForEach-Object aplica el comando entre "{" "}" a cada objeto generado por Get-Process.
    • La variable $_ hace referencia al enésimo objeto tratado. De modo que $_.name hace referencia a la propiedad name del objeto y $_.ID a la propiedad ID.

    Para poner en práctica este script, es preciso que abramos varias ventanas de Notepad.

    Quizá queramos detener más de un programa (no solo notepad). En tal caso, la definición de la variable debería haber sido $proceso = "notepad", "calc"

    Variables

    Una variable se define desde el primer momento con el símbolo $ delante. Por ejemplo: $mivar="valor". Otra característica de las variables en PowerShell es que pueden contener comandos, o secuencias de comandos. Por ejemplo:

    $procesos=Get-Process | sort cpu -Descending $procesos | select name, id, cpu -First 2 | format-table -auto

    Además existen algunas variables especiales. No se deben crear variables con estos nombres, ya que podría producir resultados inesperados:

    Condiciones

    Existen varias formas de hacer comprobaciones. Contamos con los siguientes operadores de comparación: -eq, -ne, -ge, -gt, -lt, -le, -like, -notlike, -match, -notmatch, -contains, -notcontains, -is, -isnot

    También tenemos operadores lógicos: -and, -or, -xor y -not.

    IF

    $result = if(Get-Process -Name notepad) { "Running" } else { "Not running" }

    While

    $i = 0 While ($i -lt 5) { "`$i es igual a $i, menor que 5" $i++ } #end while $i lt 5

    El bucle for

    for($cont = 1; $cont -le 10; $cont++) { "Iteración número $cont" }

    El bucle foreach

    foreach($file in dir) { "Archivo: " + $file.fullname + " ; Longitud del archivo: " + $file.Length }

    do..while

    $response = "" do { $response = Read-Host "Type something" } while($response -ne "QUIT")

    do..until

    $response = "" do { $response = Read-Host "Type something" } until($response -eq "QUIT")

    Funciones y parámetros

    Las funciones nos permiten definir bloques de código, que se comportan como un "máquina" que toman una entrada y generan una salida. Una función sencilla tiene el siguiente aspecto:

    Function Fecha { Get-Date }

    Esta función devuelve el tiempo. Si creamos un script llamado "mifuncion.ps1" con dicho contenido, para poder usar la función debemos primero ejecutar el script.

    Parámetros

    Una función puede tomar parámetros. Existen varias formas de introducir parámetros:

    El primer método consiste en indicar una secuencia de parámetros separados por comas del siguiente modo:

    Function Suma ($x, $y) { $Resp = $x + $y Write-Host "La resupesta es $Resp" }

    Para poder usar esta función, lo haremos de la siguiente forma:

    Suma 10 12

    o bien

    Suma -x 10 -y 12

    El segundo método consiste en utilizar la palabra Param, con la lista de parámetros separados por comas, del siguiente modo:

    Function Suma { Param($x, $y) $Resp = $x + $y Write-Host "La resupesta es $Resp" }

    El tercer método consiste en utilizar la variable especial $Args que se trata de un array con los parámetros introducidos. Por ejemplo:

    Function Suma { $Resp = $args[0] + $args[1] Write-Host "La resupesta es $Resp" }

    Tipos de datos

    PowerShell asigna los tipos de datos de manera automática. Sin embargo puede ser necesario definir el tipo de datos esperado para cada parámetro. Los tipos de datos soportados son:

    • [int] entero de 32 bits
    • [long] entero de 64 bits
    • [string] cadena de texto
    • [char] carácter unicode
    • [byte] carácter de 8 bits
    • [bool] valor booleano (true/false)
    • [decimal] decimal de 128 bits
    • [single] punto flotante de 32 bits
    • [double] punto flotante de 64 bits
    • [xml] objeto Xml
    • [array] array
    • [hashtable] tabla hash

    Para definir los tipos de los parámetros de una función, utilizamos la siguiente sintaxis:

    Function Suma { Param( [int]$x=0, [int]$y=0 ) $Resp = $x + $y Write-Host "La resupesta es $Resp" }

    Donde se indica que los dos parámetros son enteros, y que su valor por defecto es 0.

    Tomar el objeto procedente de la tubería

    Observa la siguiente función:

    Function EncontrarCarpeta { Param( [string]$carpeta="Windows" ) if (!$input) { Write-Host "No hay objeto de entrada" } else { $input | foreach { if ($_.Name -eq $carpeta){ Write-Host "Carpeta $carpeta encontrada!" } } } }

    La particularidad de esta variable es que nos permite hacer lo siguiente:

    Get-ChildItem -Path C:\ | EncontrarCarpeta

    Es decir, permite recoger el objeto pasado a la función a través de una tubería.

    Parámetros para un script

    Se pueden definir parámetros de entrada para un script, para ser añadidos a la ejecución del mismo. Por ejemplo, imaginemos un script llamado "cadenas.ps1":

    param([string]$foo = "foo", [string]$bar = "bar") Write-Host "Argumento `$foo: $foo" Write-Host "Argumento `$bar: $bar"

    Para ejecutar este script, podríamos hacer lo siguiente:

    C:\psscripts\foo.ps1 -foo "foo" -bar "bar"

    Usar funciones definidas en otros scripts

    Imaginemos el siguiente script, llamado "funciones.ps1":

    Function Sumar1($intIN) { $intIN + 1 } Function Sumar2($intIN) { $intIN + 2 }

    Si quisiéramos llamar estas funciones desde otro script, deberíamos primero indicar el script que las contiene, en este caso "funciones.ps1". Supongamos ahora el siguiente script, llamado "llamafunciones.ps1":

    . "c:\fso\include.ps1" Sumar1 -intIn 3 Sumar2 -intIn 3 Remove-Item function:\Sumar*

    Actividad 11. Consulta el siguiente enlace, que muestra un script para hacer copias de seguridad. Analízalo hasta comprender cada acción que lleva a cabo.

    Coméntalo en clase.