Paramètres powershell mutuellement exclusifs

scénario

  • j'écris un cmdlet pour Powershell 2.0 en utilisant Visual Studio 2008 et .NET 3.5
  • le cmdlet nécessite 3 arguments.

mon but grammaire de l'applet de commande est quelque chose comme ceci:

cmdletname [foo|bar] p1, p2
  • Qui se lit comme l'utilisateur doit donner une valeur pour "-foo", "bar", mais ne peut pas donner les deux ensemble.

EXEMPLE D'ENTRÉE VALIDE

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

EXEMPLE D'INVALIDE INPUT

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

MA QUESTION

  • Ma question est comment faire en powershell afin qu'il ne la vérification pour moi - ou, si cela est possible.
  • je sais que je peux utiliser juste deux paramètres facultatifs pour les foo et bar et simplement faire la vérification des erreurs manuellement. C'est comme ça que je le fais mettre en œuvre actuellement.
  • alternativement, je suis intéressé par des suggestions pour différentes approches.
20
demandé sur namenlos 2009-11-20 02:08:15

3 réponses

voici un exemple d'utilisation de ParameterSetName pris dans un cmdlet dans le PowerShell Communauté Extensions. BTW, pour des idées, vous pouvez parcourir le code source de PSCX.

[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;
            }
        });
    }
    ...
}

notez que le cmdlet déclare typiquement un ParameterSetName par défaut qui aide PowerShell à déterminer le paramètre" default " à utiliser lorsqu'il y a ambiguïté. Plus tard, si nécessaire, vous pouvez déterminer le jeu de paramètres en vigueur en interrogeant cette.ParameterSetName comme le l'instruction switch fait ci-dessus dans la commande EndProcessing() override.

8
répondu Keith Hill 2009-11-20 03:22:17

Vous pouvez utiliser le paramètre de l'attribut pour déclarer plusieurs jeux de paramètres. Vous assignez alors simplement des paramètres qui sont mutuellement exclusifs à des ensembles de paramètres différents.

EDIT:

ceci est également documenté dans 'about_Functions_Advanced_Parameters', sous la section "Parametersetname Named Argument". C'est ainsi que différents ensembles de paramètres sont traités avec des cmdlets comme Get-Random (qui est mutuellement exclusif les paramètres):

> 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

Voici un exemple de le faire dans une fonction:

function exclusive_params() { 
    param( 
        [parameter(ParameterSetName="seta")]$one,
        [parameter(ParameterSetName="setb")]$two, 
        $three 
    )
    "one: $one"; "two: $two"; "three: $three" 
}

paramètres one et two sont dans des ensembles de paramètres différents, de sorte qu'ils ne peuvent pas être spécifiés ensemble:

> 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

ce qui est la même erreur que j'ai eu avec Get-Random. Mais je peux utiliser les paramètres indépendamment:

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

...ou:

> exclusive_params -two bar -three third
one:
two: bar
three: third
37
répondu Joey 2012-10-17 15:31:56

je suis venu ici mais avec une exigence supplémentaire: des paramètres optionnels mutuellement exclusifs.

Ce post ici m'a aidé à trouver la moitié de la réponse. Donc j'ai pensé à poster ici la réponse complète au cas où quelqu'un aurait les mêmes exigences.

le code ci-dessous peut être utilisé au sommet D'un script Powershell pour avoir 4 paramètres optionnels dont LaunchAsAdmin et LaunchAsCouponBrowser sont mutuellement exclusifs tandis que token et WorkstationName sont également optionnels mais peuvent être combiné avec tout autre paramètre.

[CmdletBinding(DefaultParametersetName="default")]                  
Param(
    [string]$token,
    [string]$WorkstationName,
    [parameter(ParameterSetName="seta")][switch]$LaunchAsAdmin,
    [parameter(ParameterSetName="setb")][switch]$LaunchAsCouponBrowser  
)
0
répondu Michael Hafner 2018-07-11 15:49:42