Pide tu presupuesto ya!
1st February 2024
Una de las características más interesantes pero complejas de las funciones avanzadas de PowerShell son los parámetros dinámicos y el uso de esa característica para realizar la validación de parámetros de PowerShell. Los parámetros dinámicos llevan los parámetros de función típicos a un nivel completamente nuevo.
¿Alguna vez ha tenido un momento en el que creó una función avanzada y quiso que sus parámetros dependieran de otra cosa? a dinamicamente ¿Se creará en función de los criterios que elija en tiempo de ejecución?
¿Qué tal querer la validación de parámetros de Powershell como crear un PowerShell? ValidateSet ¿Matriz que proporciona finalización de tabulación en un parámetro que no se basa en un conjunto estático de picaduras sino que se genera en tiempo de ejecución? Ambos son factibles con parámetros dinámicos.
Esta publicación es parte de la serie PowerShell Blogging Week (#PSBlogWeek) sobre funciones avanzadas de Windows PowerShell, una serie de publicaciones coordinadas diseñadas para brindar una visión integral de un tema en particular.
En esta serie, también tenemos:
Para sugerir un tema de la Semana de blogs de PowerShell, deje un comentario o envíenos un tweet con el hashtag #PSBlogWeek.
Hay un par de formas diferentes de utilizar parámetros dinámicos que he visto. La primera es la forma en que Ben Ten escribió sobre ellos en la revista PowerShell. Con este método, Ben pudo crear parámetros sobre la marcha en función de si se utilizaba un parámetro diferente. Personalmente, nunca he tenido la necesidad de hacer esto.
Realmente me gusta usar parámetros dinámicos como una forma de validar entrada basada en algunos criterios que están disponibles en tiempo de ejecución. De esta manera puedo escribir un script que recopile información sobre la marcha, lo que me permite completar la hermosa pestaña de parámetros que todos conocemos y amamos.
Repasemos un ejemplo sobre cómo crear una validación de parámetros de Powershell basada en archivos en una carpeta.
Los parámetros de funciones avanzadas “normales” le permiten utilizar algunos Validate opciones. Puede validar la cantidad de argumentos que un parámetro puede aceptar, la longitud mínima y máxima de un argumento de parámetro, un conjunto de opciones en una matriz, la coincidencia de una cadena de expresiones regulares o un bloque de secuencia de comandos y más. Lo que estoy buscando aquí es usar el ValidateSet atributo para completar la pestaña.
Notarás que en el ejemplo anterior estoy usando el Get-Item cmdlet y los parámetros predeterminados para la finalización de tabulación que se espera. Quiero esa funcionalidad pero quiero completar con tabuladores mis propios argumentos, así que creemos una función simple para hacerlo.

Notarás que he resaltado el atributo de validación que nos permitirá completar con pestañas el MyParameter argumento. Ahora podemos completar la tabulación del argumento de parámetro personalizado utilizando los valores especificados en PowerShell. ValidateSet atributo de matriz.

Pero, ¿qué pasa ahora si quiero que mis opciones para completar tabulaciones se generen sobre la marcha en función de algún otro criterio en lugar de una lista estática? La única opción es utilizar parámetros dinámicos. En mi ejemplo, quiero completar con pestañas una lista de archivos en una carpeta particular en tiempo de ejecución.
Para hacer esto, usaré un parámetro dinámico que se ejecutará Get-ChildItem cada vez que intento completar con tabulaciones el MyParameter parámetro.
Dicho esto, hagamos el ValidateSet atributo de la MyParameter dinámica de parámetros, ¿de acuerdo?
La primera diferencia entre un parámetro estándar y un parámetro dinámico que notará es que los parámetros dinámicos están en su propio bloque.
[CmdletBinding()]
param()
DynamicParam {
}
Dentro de DynamicParam El bloque es donde ocurre la magia. Y toma un tiempo entender la magia.
Un parámetro dinámico es, en cierto sentido, un System.Management.Automation.RuntimeDefinedParameterDictionary objeto con uno o más System.Management.Automation.RuntimeDefinedParameter objetos en su interior. Pero no es tan fácil. Analicémoslo.
System.Management.Automation.RuntimeDefinedParameterDictionary objeto para usar como contenedor para uno o más parámetros que le agregaremos usando$RuntimeParamDic = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary.
2. A continuación, cree el System.Collections.ObjectModel.Collection preparado para contener System.Attribute objetos.
$AttribColl = New-Object System.Collections.ObjectModel.Collection[System.Attribute].
3. Ahora cree una instancia de System.Management.Automation.ParameterAttribute objeto que contendrá todos los atributos de parámetros a los que estamos acostumbrados. En nuestro ejemplo, estoy definiendo mi parámetro para que esté en todos los conjuntos de parámetros y acepte la entrada de canalización mediante un objeto de canalización y por nombre de propiedad.
$ParamAttrib = New-Object System.Management.Automation.ParameterAttribute
$ParamAttrib.Mandatory = $Mandatory.IsPresent
$ParamAttrib.ParameterSetName="__AllParameterSets"
$ParamAttrib.ValueFromPipeline = $ValueFromPipeline.IsPresent
$ParamAttrib.ValueFromPipelineByPropertyName = $ValueFromPipelineByPropertyName.IsPresent
4. Agregue nuestro conjunto de atributos de parámetros a la colección que creamos una instancia anteriormente.
$AttribColl.Add($ParamAttrib)
5. Como estoy usando este parámetro dinámico para crear una matriz ValidateSet de PowerShell para la validación de parámetros, también debo incluir un System.Management.Automation.ValidateSetAttribute objeto dentro de nuestra colección de atributos. Aquí es donde define el código para crear los valores que nos permiten completar con tabuladores los argumentos de los parámetros.
$AttribColl.Add((New-Object System.Management.Automation.ValidateSetAttribute((Get-ChildItem C:\TheAwesome -File | Select-Object -ExpandProperty Name))))
6. Luego tenemos que crear una instancia de un System.Management.Automation.RuntimeDefinedParameter objeto usando el nombre del parámetro, su tipo y la colección de atributos a la que hemos estado agregando cosas.
$RuntimeParam = New-Object System.Management.Automation.RuntimeDefinedParameter('MyParameter', [string], $AttribColl)
7. Una vez que finaliza el parámetro de tiempo de ejecución, volvemos al objeto de diccionario original del que creamos una instancia anteriormente usando el nombre del parámetro y el objeto de parámetro de tiempo de ejecución que creamos.
$RuntimeParamDic.Add('MyParameter', $RuntimeParam)
8. Luego podemos devolver este objeto de diccionario de tiempo de ejecución al bloque de parámetros dinámicos y ¡listo!
¿Ya se te han puesto vidriosos los ojos? La mía fue cuando intenté resolver esto por primera vez.
Siendo el administrador vago que soy, creé una función llamada New-ValidationDynamicParam eso hace todo este trabajo por usted creando la matriz ValidateSet de PowerShell. Simplemente pase el nombre del parámetro, los atributos que desea que tenga el parámetro y el código que usará para crear la validación y ¡listo! La función hace el resto.
New-ValidationDynamicParam -Name 'MyParameter' -Mandatory -ValidateSetOptions (Get-ChildItem C:\TheAwesome -File | Select-Object -ExpandProperty Name)
¡Mi dolor es vuestra ganancia, gente!
Ahora, con nuestro parámetro de validación dinámica creado, probémoslo.
Tengo algunos archivos en un directorio de mi computadora que solo quiero que se pasen al MyParameterparámetro.

Ahora todo lo que tengo que hacer es ejecutar nuestro script y ¡listo! ¡Ahora solo puedo usar los nombres de los archivos como argumentos de parámetros y se actualizan a medida que los archivos entran y salen de la carpeta!

Leave a comment