Powershell Get命令-使用动态参数时,语法仅返回第一组参数
我很难理解Powershell在使用动态参数时如何解析语法 一个简单、可重复的示例:Powershell Get命令-使用动态参数时,语法仅返回第一组参数,powershell,Powershell,我很难理解Powershell在使用动态参数时如何解析语法 一个简单、可重复的示例: using System; using System.Management.Automation; namespace SOQuestion { [Cmdlet(VerbsCommon.Get, "Greeting")] public class GetGreeting : PSCmdlet, IDynamicParameters { [Parame
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命令Get Greeting-syntax
时,我得到:
获取问候语[-NameType][-FirstName][]
这些是属于DynParamsFirst
的参数。没有迹象表明参数是动态的。我发现正在拉取的语法是NameType
enum中第一个匹配的语法-如果我在NameType
enum中将Full
设置为0
,那么Get命令Get Greeting-syntax
将输出DynParamsFull
的参数。另外,最有可能是相关的,如果我在没有参数的情况下输入Get Greeting
,然后按enter键,我总是只会得到FirstName
,这将与完整的
名称类型组合抛出一个错误
我觉得这很令人惊讶,而且很难对命令进行记录。我还发现,提出一个恰当的问题并非小事
下面是:如何更改代码,以便在不带参数的情况下输入命令时,Powershell会意识到涉及到动态参数?
-NameType
是cmdlet唯一的静态参数。它的默认值是隐式[NameType]::new()
,即[NameType]
类型的隐式默认值:作为枚举
-派生类型,即作为.NET值类型,它隐式具有一个默认构造函数,该构造函数将值初始化为全零,在您的情况下,该构造函数将转换为名称类型。首先
:
因此,如果没有(隐含的)附加上下文,Get命令Get Greeting-Syntax
的行为就像您将-NameType First
传递给Get Greeting
,这就是您看到的语法图:它显示了相应的-FirstName
动态参数:
PS>Get命令Get Greeting-syntax#暗示:-Args'-NameType',First-见下文。
获取问候语[-NameType][-FirstName][]
为了查看其他语法图可能适用于何种情况,您必须通过其-ArgumentList
/-arguments
参数将参数传递给Get Command-syntax
,该参数随后显示了适当的语法,就好像这些参数被传递给了目标命令一样,获取问候语
:
PS>Get命令Get Greeting-syntax-Args'-NameType',完整
获取问候语[-NameType][First][Last][]
请注意,可能需要引用
-NameType
,以免它被解释为另一个参数名,而不是传递给-Args
-请参见。查看cmdlet向您显示的内容<代码>示例2:跟踪ParameterBinding操作的操作极好的解释和一个有用的注释,我不知道如何查看其他动态参数集。需要指出的是-如果您不想显示动态参数,除非特别定义了一个值,那么在检查NameType的值之前,请检查ifMyInvocation.BoundParameters.ContainsKey(nameof(NameType))
-这将告诉您用户是否指定了一个NameType
,而不是默认值(NameType),而不使用可为空的(因此对最终用户更清楚)。非常有用,谢谢。从可发现性的角度来看,您是否认为上述实现的设计很差?@Rno,可发现性确实很棘手。典型的用例是动态参数取决于提供程序上下文,其中当前位置($PWD
)隐式地提供上下文并自动显示动态参数。这就是为什么当当前位置是文件系统位置时,Get ChildItem-?
显示由文件系统
提供程序添加的动态-目录
参数(这是典型的)@Rno,在您的情况下,也许更好的方法是只使用静态参数,并简单地将-Last
设置为可选。一般来说,可以帮助您实现不同的(静态)参数集参数组合,因此您可以将Get Greeting-FirstName
作为一个集合,并将Get Greeting-First-Last
作为另一个集合。@mklement0谢谢您的输入,它非常有启发性。FWIW我通过为每个枚举值创建开关参数来模拟参数集的动态方法。这在技术上是虽然-syntax参数很好地输出了它,但它比“undiscoverable”语法更容易混淆UX。它还存在另一个问题:我无法充分利用IArgumentCompleter
。但我现在离题了。再次感谢。