首页 > 解决方案 > Get-Command -syntax 在使用动态参数时只返回第一组参数

问题描述

我很难理解 Powershell 在使用动态参数时如何解析语法。

一个简单的、可重现的例子:

using System;
using System.Management.Automation;

namespace SOQuestion
{
    [Cmdlet(VerbsCommon.Get, "Greeting")]
    public class GetGreeting : PSCmdlet, IDynamicParameters
    {
        [Parameter(Position = 0, Mandatory = true)]
        public NameType NameType { get; set; }

        private object context;
        public object GetDynamicParameters()
        {
            switch (NameType)
            {
                case NameType.First:
                    context =  new DynParamsFirst();
                    return context;
                case NameType.Full:
                    context = new DynParamsFull();
                    return context;
                default:
                    throw new ArgumentException("Invalid type specified");
            }
        }
        protected override void ProcessRecord()
        {
            string name;
            switch (NameType)
            {
                case NameType.First:
                    DynParamsFirst first = context as DynParamsFirst;
                    name = first.FirstName;
                    break;
                case NameType.Full:
                    DynParamsFull full = context as DynParamsFull;
                    name = full.First + " " + full.Last;
                    break;
                default:
                    throw new ArgumentException("Invalid type specified");
            }
            WriteObject($"Hello {name}!");
        }
    }

    public enum NameType
    {
        First = 0,
        Full = 1
    }

    public class DynParamsFirst
    {
        [Parameter(Position = 1, Mandatory = true)]
        public string FirstName { get; set; }
    }

    public class DynParamsFull
    {
        [Parameter(Position = 1, Mandatory = true)]
        public string First { get; set; }
        [Parameter(Position = 2, Mandatory = true)]
        public string Last { get; set; }
    }
}

在 CLI 中提供参数时,这会按预期运行,我的参数是动态的,并且我得到了预期的输出。

但是当我跑步时,Get-Command Get-Greeting -syntax我得到:

Get-Greeting [-NameType] <NameType> [-FirstName] <string> [<CommonParameters>]

这些是属于的参数DynParamsFirst。没有迹象表明参数是动态的。我发现被提取的语法是枚举中第一个匹配的语法NameType- 如果我在枚举中设置Full为,那么将输出参数代替。此外,最可能相关的是,如果我不带参数输入并按 Enter,我总是得到 just ,这与NameType结合会引发错误。0NameTypeGet-Command Get-Greeting -syntaxDynParamsFullGet-GreetingFirstNameFull

我发现这令人惊讶,并且很难记录命令。我还发现提出一个适当的问题并非易事。

这里有:如何更改代码,以便在输入不带参数的命令时,Powershell 知道涉及动态参数?

标签: powershell

解决方案


-NameType是您的 cmdlet 的唯一静态参数。它的默认值是隐式的[NameType]::new(),即[NameType]类型的隐式默认值:作为enum派生类型,即作为 .NET值类型,它隐式具有将值初始化为全零的默认构造函数,在您的情况下转换为NameType.First

因此,在没有(隐含的)额外上下文的情况下,Get-Command Get-Greeting -Syntax其行为就像您已传递-NameType First给一样Get-Greeting,这就是您看到的语法图:它显示了相应的-FirstName动态参数:

PS> Get-Command Get-Greeting -syntax # implies: -Args '-NameType', First - see below.

Get-Greeting [-NameType] <NameType> [-FirstName] <string> [<CommonParameters>]

为了查看其他语法图可能适用于情景,您必须通过它的/参数传递传递参数,然后显示适合情景的语法,_就像这些参数被传递给目标命令一样:Get-Command -Syntax-ArgumentList-ArgsGet-Greeting

PS> Get-Command Get-Greeting -syntax -Args '-NameType', Full

Get-Greeting [-NameType] <NameType> [-First] <string> [-Last] <string> [<CommonParameters>]

请注意可能令人惊讶的引用 -NameType,以免它被解释为另一个参数名称而不是传递给的参数-Args- 请参阅GitHub 问题 #4624


推荐阅读