Módulo Powershell: parámetros jerárquicos dinámicos obligatorios

Entonces, lo que realmente quiero es completar la pestaña de alguna manera utilizable en un módulo PS. ValidateSet parece ser el camino a seguir aquí.

Lamentablemente, mis datos son dinámicos, por lo que no puedo anotar el parámetro con todos los valores válidos por adelantado. DynamicParameters / IDynamicParameters parece ser la solución paraese problema.

Al unir estas cosas (y reducir mi falla a un simple caso de prueba) terminamos con:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Management.Automation;
using System.Text;
using System.Threading.Tasks;

namespace PSDummy
{
    [Cmdlet(VerbsCommon.Get, "BookDetails")]
    public class GetBookDetails : Cmdlet, IDynamicParameters
    {
        IDictionary<string, string[]> m_dummyData = new Dictionary<string, string[]> {
            {"Terry Pratchett", new [] {"Small Gods", "Mort", "Eric"}},
            {"Douglas Adams", new [] {"Hitchhiker's Guide", "The Meaning of Liff"}}
        };

        private RuntimeDefinedParameter m_authorParameter;
        private RuntimeDefinedParameter m_bookParameter;

        protected override void ProcessRecord()
        {
              // Do stuff here..
        }

        public object GetDynamicParameters()
        {
            var parameters = new RuntimeDefinedParameterDictionary();

            m_authorParameter = CreateAuthorParameter();
            m_bookParameter = CreateBookParameter();

            parameters.Add(m_authorParameter.Name, m_authorParameter);
            parameters.Add(m_bookParameter.Name, m_bookParameter);
            return parameters;
        }

        private RuntimeDefinedParameter CreateAuthorParameter()
        {
            var p = new RuntimeDefinedParameter(
                "Author",
                typeof(string),
                new Collection<Attribute>
                {
                    new ParameterAttribute {
                        ParameterSetName = "BookStuff",
                        Position = 0,
                        Mandatory = true
                    },
                    new ValidateSetAttribute(m_dummyData.Keys.ToArray()),
                    new ValidateNotNullOrEmptyAttribute()
                });

            // Actually this is always mandatory, but sometimes I can fall back to a default
            // value. How? p.Value = mydefault?

            return p;
        }

        private RuntimeDefinedParameter CreateBookParameter()
        {
            // How to define a ValidateSet based on the parameter value for
            // author?
            var p = new RuntimeDefinedParameter(
                "Book",
                typeof(string),
                new Collection<Attribute>
                {
                    new ParameterAttribute {
                        ParameterSetName = "BookStuff",
                        Position = 1,
                        Mandatory = true
                    },
                    new ValidateSetAttribute(new string[1] { string.Empty }/* cannot fill this, because I cannot access the author */),
                    new ValidateNotNullOrEmptyAttribute()
                });

            return p;
        }
    }
}

Desafortunadamente, este pequeño fragmento ya causa muchos problemas. Orden descendiente:

No veo cómo puedo crear una conexión entre los parámetros. Si elige un autor, solo debería poder elegir un libro que coincida con el autor. Hasta aquíGetDynamicParameters() Sin embargo, siempre parece apátrida: no veo forma de acceder al valor de un parámetro dinámico diferente / anterior. Intenté mantenerlo en un campo, intenté buscarMyInvocation - sin suerte. ¿Es eso posible?

¿Cómo define un valor predeterminado para el parámetro obligatorio? No se ajusta al ejemplo tonto, pero digamos que puede almacenar su autor favorito. De ahora en adelante, quiero usar ese autor por defecto, pero todavía es obligatorio tener un puntero a un autor. O me diste un valor predeterminado (y aún puedes especificar algo más) o necesitas ser explícito.

La finalización de tabulación para cadenas con espacios parece extraña / rota / limitada, porque no encierra el valor entre comillas (como cmd.exe haría, por ejemplo, si escribedir C:\Program <tab>) Entonces, completar la pestañarompe la invocación (si se resolvieran los problemas anteriores,Get-BookDetails Ter<tab> se expandiría aGet-BookDetails Terry Pratchett que pone el apellido en la posición del parámetro 1, también conocido como 'libro'.

No debería ser tan difícil, ¿seguramente alguien ya hizo algo similar?

Actualización: Después de otro buen día de jugar y perder el tiempo, no veo una manera de hacer que esto funcione. El comando no tiene estado y se instanciará una y otra vez. En el momento en que yopuede definir parámetros dinámicos (GetDynamicParameters) No puedo acceder a sus valores (actuales) / ver a qué estarían vinculados, p. MyInvocation.BoundParameters es cero. Dejaré la pregunta abierta, pero parece que esto simplemente no es compatible. Todos los ejemplos que veo agregan un parámetro dinámico basado en el valor de uno estático, y eso no es relevante aquí. Tío.

Respuestas a la pregunta(1)

Su respuesta a la pregunta