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.
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.
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
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
)