Share via


Windows PowerShell: Creación de una función mejor

Las funciones avanzadas de Windows PowerShell 2.0 permiten emular cmdlets nativos mediante scripts relativamente sencillos.

Don Jones

En Windows PowerShell 2.0, Microsoft introdujo a un nuevo tipo de función denominado "función avanzada". Mucha gente lo llame en un cmdlet de secuencia de comandos de"." La idea con estas funciones es que ahora puede utilizar el lenguaje de scripting simplificado de Windows PowerShell para crear algo parecido, obras, olores y se siente casi exactamente como un cmdlet de Windows PowerShell real, nativo.

Obviamente, no todos se van a estar en condiciones de crear herramientas reutilizables para usted y sus compañeros de trabajo. Sin embargo, si está creando herramientas reutilizables, estas funciones avanzadas son la única manera de ir. De hecho, estoy modificando mi curso de aula para enseñar sólo este tipo de función.

Dado que avanzada funcionan tanto como cmdlets reales, una función realizada correctamente puede ser más fácil que otros usuarios utilicen porque se "ajuste" con la forma en el resto de las obras de shell. Ese es el caso, aquí una plantilla que puede utilizar más rápidamente crear estas funciones avanzadas:

function Get-Something {
  <#
  .SYNOPSIS
  Describe the function here
  .DESCRIPTION
  Describe the function in more detail
  .EXAMPLE
  Give an example of how to use it
  .EXAMPLE
  Give another example of how to use it
  .PARAMETER computername
  The computer name to query. Just one.
  .PARAMETER logname
  The name of a file to write failed computer names to. Defaults to errors.txt.
  #>
  [CmdletBinding()]
  param
  (
    [Parameter(Mandatory=$True,
    ValueFromPipeline=$True,
    ValueFromPipelineByPropertyName=$True,
      HelpMessage='What computer name would you like to target?')]
    [Alias('host')]
    [ValidateLength(3,30)]
    [string[]]$computername,
        
    [string]$logname = 'errors.txt'
  )

  begin {
  write-verbose "Deleting $logname"
    del $logname -ErrorActionSilentlyContinue
  }

  process {

    write-verbose "Beginning process loop"

    foreach ($computer in $computername) {
      Write-Verbose "Processing $computer"
      # use $computer to target a single computer
    

      # create a hashtable with your output info
      $info = @{
        'info1'=$value1;
        'info2'=$value2;
        'info3'=$value3;
        'info4'=$value4
      }
      Write-Output (New-Object –TypenamePSObject –Prop $info)
    }
  }
}

Hay algunos aspectos importantes que tenga en cuenta acerca de esta función, muchas de las cuales deberá ajustar al utilizar esta plantilla:

  • El nombre de la función debería parecerse a un nombre de cmdlet, empezando por uno de los verbos de Windows PowerShell utilizados como "Get" y terminan con un sustantivo singular.
  • Rellene la Ayuda basada en el comentario. Proporcionar una descripción de cada parámetro, una descripción de la función general y ejemplos de cómo se utiliza. Ejecute about_comment_based_help de ayuda para obtener más información sobre la escritura de Ayuda de esta manera.
  • El primer parámetro, computername $, es bastante complejo. Puede aceptar uno o más valores del parámetro o de la canalización. Sólo acepta valores que tres a 30 caracteres. Puede utilizar –host en lugar de – computername al ejecutar la función. Este parámetro es obligatorio. Si alguien ejecuta la función sin proporcionar un nombre de equipo, el shell les pedirá que escriba una o más.
  • El segundo parámetro, $logname, es un parámetro más simple. Sólo acepta un valor de cadena. También tiene un valor predeterminado.
  • El bloque de secuencia de comandos de inicio intenta eliminar el archivo de registro existente, por lo que cada ejecución de la función tiene un nuevo archivo de registro.
  • En el bloque de secuencia de comandos de proceso, he indicado donde utilizaría la variable de equipo $ para que la función trabaje con un solo equipo. No trabaja directamente con $NombreDeEquipo. Ese parámetro puede contener uno o más valores, por lo que el bucle ForEach enumera y sólo uno en uno coloca en el equipo de $ para usted.
  • La tabla de hash de $info debe contener el formato de salida deseado. Considérelo como salida tabular. He creado columnas denominadas información 1, la información 2, la información 3 y la información 4. Se extraen los valores de las columnas de las variables de valorX $. Esto es sólo un ejemplo. No he realmente pongo nada en esas variables en esta plantilla, para que pueda reemplazar $valor1, valor2 $, etc. con su propia información.

Esta plantilla es buena para cualquier función avanzada que necesita para obtener información, pero en realidad no realizar cambios en el estado del sistema. Para las funciones avanzadas que cambiarán el estado del sistema, deberá implementar algunos elementos adicionales. Con eso en mente, aquí es una plantilla de la segunda:

function Do-Something {
  <#
  .SYNOPSIS
  Describe the function here
  .DESCRIPTION
  Describe the function in more detail
  .EXAMPLE
  Give an example of how to use it
  .EXAMPLE
  Give another example of how to use it
  .PARAMETER computername
  The computer name to query. Just one.
  .PARAMETER logname
  The name of a file to write failed computer names to. Defaults to errors.txt.
  #>
  [CmdletBinding(SupportsShouldProcess=$True,ConfirmImpact='Low')]
  param
  (
    [Parameter(Mandatory=$True,
    ValueFromPipeline=$True,
    ValueFromPipelineByPropertyName=$True,
      HelpMessage='What computer name would you like to target?')]
    [Alias('host')]
    [ValidateLength(3,30)]
    [string[]]$computername,
        
    [string]$logname = 'errors.txt'
  )

  begin {
  write-verbose "Deleting $logname"
    del $logname -ErrorActionSilentlyContinue
  }

  process {

    write-verbose "Beginning process loop"

    foreach ($computer in $computername) {
      Write-Verbose "Processing $computer"
      if ($pscmdlet.ShouldProcess($computer)) {
        # use $computer here
      }
    }
  }
}

En esta plantilla, deberá modificar la configuración de "ConfirmImpact". Debe dar una indicación relativa al peligro potencial de la función avanzada. Por ejemplo, haciendo algo menor como cambiar el atributo de sólo lectura de un archivo puede clasificar un ConfirmImpact de "Baja". Reiniciar el equipo podría ser un ConfirmImpact de "Alta". Windows PowerShell utiliza esta opción, junto con la variable de ConfirmPreference de $ integrada del shell, para determinar si se proporciona automáticamente preguntas "¿está seguro?" cuando ejecuta la función.

Ha observado donde debe realmente realizar la acción, utilizando el equipo de $ a un único equipo de destino. Que se ajusta en una construcción "If", que utiliza el objeto de pscmdlet $ integrados. Si esta función se ejecuta con los parámetros de la – WhatIf o: – Confirm (que se admite), el objeto de pscmdlet $ se ocupará de producir el resultado "what if" o generar las preguntas "¿está seguro?".

Ambas plantillas también admite el parámetro –verbose y utilizar Write-Verbose para generar mensajes de estado mientras se ejecuta la función. Obviamente, no todas las funciones tendrá que los equipos de destino. A veces, querrá parámetros para aceptar los nombres de archivo, nombres de usuario u otra información. Sólo tiene que modificar las declaraciones de parámetro correctamente.

Puede encontrar más información sobre los atributos de parámetro — como la validación, obligatoria, canalización entrada y así sucesivamente, mediante la ejecución de Ayuda de about_functions_advanced_parameter en el shell. Que disfrute.

Don Jones

Don Joneses un popular Windows PowerShell autor, instructor y altavoces. Su libro más reciente es "Aprender Windows PowerShell en un mes de almuerzos" (Manning, 2011); visite MoreLunches.com para información y libre companion de contenido. Él también está disponible para las clases de formación in situ (visite ConcentratedTech.com/training para obtener más información).

Contenido relacionado