我想要的cmdlet语法是这样的:
cmdletname [foo|bar] p1, p2
cmdletname -foo xxx -p1 hello -p2 world
cmdletname -bar yyy -p1 hello -p2 world
cmdletname -foo xxx -bar yyy -p1 hello -p2 world
答案 0 :(得分:42)
您可以使用parameter attribute声明多个参数集。然后,您只需分配与不同参数集互斥的参数。
修改强>
“about_Functions_Advanced_Parameters”中的“ParameterSetName Named Argument”部分也记录了这一点。这就是使用像Get-Random
这样的cmdlet处理不同参数集的方式(它具有互斥参数):
> get-random -input 4 -max 77
Get-Random : Parameter set cannot be resolved using the specified named parameters.
At line:1 char:11
+ get-random <<<< -input 4 -max 77
+ CategoryInfo : InvalidArgument: (:) [Get-Random], ParameterBindingException
+ FullyQualifiedErrorId : AmbiguousParameterSet,Microsoft.PowerShell.Commands.GetRandomCommand
以下是在函数中执行此操作的示例:
function exclusive_params() {
param(
[parameter(ParameterSetName="seta")]$one,
[parameter(ParameterSetName="setb")]$two,
$three
)
"one: $one"; "two: $two"; "three: $three"
}
参数one
和two
位于不同的参数集中,因此无法一起指定:
> exclusive_params -one foo -two bar -three third
exclusive_params : Parameter set cannot be resolved using the specified named parameters.
At line:1 char:17
+ exclusive_params <<<< -one foo -two bar -three third
+ CategoryInfo : InvalidArgument: (:) [exclusive_params], ParameterBindingException
+ FullyQualifiedErrorId : AmbiguousParameterSet,exclusive_params
与Get-Random相同的错误。但我可以独立使用这些参数:
> exclusive_params -one foo -three third
one: foo
two:
three: third
...或:
> exclusive_params -two bar -three third
one:
two: bar
three: third
答案 1 :(得分:8)
以下是使用从PowerShell Community Extensions中的cmdlet中获取的ParameterSetName的示例。顺便说一句,对于你可以browse the PSCX source code的想法。
[Cmdlet(VerbsCommon.Set, PscxNouns.Clipboard,
DefaultParameterSetName = ParamSetText)]
[Description("Copies the item in the system clipboard.")]
[RelatedLink(typeof(GetClipboardCommand))]
[RelatedLink(typeof(OutClipboardCommand))]
[RelatedLink(typeof(WriteClipboardCommand))]
public class SetClipboardCommand : ClipboardCommandBase
{
... fields elided
const string ParamSetRtf = "Rtf";
const string ParamSetHtml = "Html";
const string ParamSetText = "Text";
const string ParamSetFiles = "Files";
const string ParamSetImage = "Image";
.
[AllowNull]
[Parameter(ValueFromPipeline = true, ParameterSetName = ParamSetImage)]
public Image Image { get; set; }
.
[AllowNull]
[AllowEmptyCollection]
[Parameter(ValueFromPipeline = true, ValueFromRemainingArguments = true,
ParameterSetName = ParamSetFiles)]
public FileSystemInfo[] Files { get; set; }
.
[AllowNull]
[AllowEmptyString]
[Parameter(ValueFromPipeline = true, ValueFromRemainingArguments = true,
ParameterSetName = ParamSetText)]
public string Text { get; set; }
.
[Parameter(ValueFromPipeline = true, ValueFromRemainingArguments = true,
ParameterSetName = ParamSetHtml)]
public string Html { get; set; }
.
[Parameter(ValueFromPipeline = true, ValueFromRemainingArguments = true,
ParameterSetName = ParamSetRtf)]
public string Rtf { get; set; }
.
protected override void ProcessRecord()
{
...
}
.
protected override void EndProcessing()
{
ExecuteWrite(delegate
{
switch (ParameterSetName)
{
case ParamSetFiles:
if (Paths.Count == 0)
WinFormsClipboard.Clear();
else
WinFormsClipboard.SetFileDropList(_paths);
break;
case ParamSetImage:
if (Image == null)
WinFormsClipboard.Clear();
else
WinFormsClipboard.SetImage(_image);
break;
case ParamSetRtf:
SetTextContents(Rtf, TextDataFormat.Rtf);
break;
case ParamSetHtml:
SetTextContents(Html, TextDataFormat.Html);
break;
default:
SetTextContents(Text, TextDataFormat.UnicodeText);
break;
}
});
}
...
}
请注意,cmdlet通常声明一个默认的ParameterSetName,它可以帮助PowerShell确定在出现歧义时要使用的“默认”参数集。稍后,如果需要,您可以通过查询this.ParameterSetName来确定哪个参数集有效,如上面的EndProcessing()覆盖中的switch语句所做的那样。
答案 2 :(得分:0)
我来这里是有一个附加要求:可选的互斥参数。
这里的帖子帮助我找到了一半答案。因此,我想将完整的答案发布在这里,以防有人有相同的要求。
下面的代码可以在Powershell脚本的顶部使用,以具有4个可选参数,其中LaunchAsAdmin和LaunchAsCouponBrowser是互斥的,而token和WorkstationName也是可选的,但可以与任何其他参数组合。
[CmdletBinding(DefaultParametersetName="default")]
Param(
[string]$token,
[string]$WorkstationName,
[parameter(ParameterSetName="seta")][switch]$LaunchAsAdmin,
[parameter(ParameterSetName="setb")][switch]$LaunchAsCouponBrowser
)