代码之家  ›  专栏  ›  技术社区  ›  namenlos

互斥的PowerShell参数

  •  22
  • namenlos  · 技术社区  · 15 年前

    脚本

    • 我正在使用Visual Studio 2008和.NET 3.5为PowerShell 2.0编写一个Cmdlet
    • Cmdlet需要3个参数。

    我预期的Cmdlet语法如下:

    cmdletname [foo|bar] p1, p2
    
    • 这意味着用户必须给出“-foo”或“-bar”的值,但不能同时给出两者。

    有效输入示例

    cmdletname -foo xxx -p1 hello  -p2 world
    cmdletname -bar yyy -p1 hello  -p2 world
    

    无效输入示例

    cmdletname -foo xxx -bar yyy -p1 hello  -p2 world
    

    我的问题

    • 我的问题是如何在PowerShell中执行此操作,以便它为我执行所有检查,或者是否可以。
    • 我知道我可以使用两个可选的foo和bar参数,只需手动进行错误检查。这就是我目前实现它的方法。
    • 或者,我对不同方法的建议感兴趣。
    3 回复  |  直到 6 年前
        1
  •  8
  •   Keith Hill    15 年前

    下面是一个示例,其中使用了从中的Cmdlet获取的ParameterSetName。 PowerShell Community Extensions . 顺便说一句,你可以 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通常声明一个默认的参数setname,它帮助PowerShell确定在存在歧义时要使用的“默认”参数集。稍后,如果需要,您可以通过查询this.parametersetname来确定哪个参数集有效,正如上面在endprocessing()重写中switch语句所做的那样。

        2
  •  40
  •   Coding Mash desirejeet    12 年前

    你可以使用 parameter attribute 声明多个参数集。然后,只需为不同的参数集分配相互排斥的参数。

    编辑:

    这也记录在“关于\u函数\u高级\u参数”部分的“参数集名称命名参数”下。这就是使用类似这样的Cmdlet处理不同参数集的方式 Get-Random (参数互斥):

    > 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
    

    这是我随机得到的相同错误。但我可以独立使用这些参数:

    > exclusive_params -one foo -three third
    one: foo
    two:
    three: third
    

    …或:

    > exclusive_params -two bar -three third
    one:
    two: bar
    three: third
    
        3
  •  0
  •   John Ranger    6 年前

    我来到这里,但有一个附加的要求:可选的互斥参数。

    这篇文章帮助我找到了一半答案。所以我想在这里张贴完整的答案,以防有人有同样的要求。

    下面的代码可用于PowerShell脚本的顶部,以具有4个可选参数,其中launchasadmin和launchascouponbrowser互斥,token和workstationname也是可选的,但可以与任何其他参数组合。

    [CmdletBinding(DefaultParametersetName="default")]                  
    Param(
        [string]$token,
        [string]$WorkstationName,
        [parameter(ParameterSetName="seta")][switch]$LaunchAsAdmin,
        [parameter(ParameterSetName="setb")][switch]$LaunchAsCouponBrowser  
    )