scripts - Parámetros de PowerShell mutuamente excluyentes.
wikipedia windows powershell (3)
GUIÓN
- Estoy escribiendo un cmdlet para Powershell 2.0 con Visual Studio 2008 y .NET 3.5
- El cmdlet requiere 3 argumentos.
Mi intención gramática del cmdlet es algo como esto:
cmdletname [foo|bar] p1, p2
- Eso se lee como el usuario debe dar un valor para "-foo" o "-bar" pero no puede dar ambos juntos.
EJEMPLO DE ENTRADA VALIDA
cmdletname -foo xxx -p1 hello -p2 world
cmdletname -bar yyy -p1 hello -p2 world
EJEMPLO DE ENTRADA NO VÁLIDA
cmdletname -foo xxx -bar yyy -p1 hello -p2 world
MI PREGUNTA
- Mi pregunta es sobre cómo hacer esto en powershell para que haga todas las comprobaciones por mí, o si es posible.
- Sé que puedo usar solo dos parámetros opcionales para foo y bar y simplemente hacer la comprobación de errores manualmente. Así es como lo tengo implementado actualmente.
- Alternativamente, estoy interesado en sugerencias para diferentes enfoques.
Este es un ejemplo del uso de ParameterSetName tomado de un cmdlet en las extensiones de la comunidad de PowerShell . Por cierto, para ideas puedes navegar por el código fuente 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;
}
});
}
...
}
Tenga en cuenta que el cmdlet generalmente declara un ParameterSetName predeterminado que ayuda a PowerShell a determinar el conjunto de parámetros "predeterminado" para usar cuando hay ambigüedad. Más adelante, si es necesario, puede determinar qué conjunto de parámetros está en vigor consultando este. ParámetroSetName como lo hace la instrucción de cambio arriba en el reemplazo de EndProcessing ().
Puede utilizar el atributo de parámetro para declarar varios conjuntos de parámetros. A continuación, simplemente asigna parámetros que son mutuamente exclusivos a diferentes conjuntos de parámetros.
EDITAR:
Esto también se documenta en ''about_Functions_Advanced_Parameters'', en la sección "ParameterSetName Named Argument". Así es como se manejan los diferentes conjuntos de parámetros con cmdlets como Get-Random
(que tiene parámetros mutuamente exclusivos):
> 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
Aquí hay un ejemplo de hacerlo en una función:
function exclusive_params() {
param(
[parameter(ParameterSetName="seta")]$one,
[parameter(ParameterSetName="setb")]$two,
$three
)
"one: $one"; "two: $two"; "three: $three"
}
Los parámetros one
y two
están en diferentes conjuntos de parámetros, por lo que no se pueden especificar juntos:
> 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
Que es el mismo error que obtuve con Get-Random. Pero puedo usar los parámetros de forma independiente:
> exclusive_params -one foo -three third
one: foo
two:
three: third
...o:
> exclusive_params -two bar -three third
one:
two: bar
three: third
Vine aquí pero con un requisito adicional: Parámetros exclusivos recíprocos opcionales.
Este post aquí me ayudó a encontrar la mitad de la respuesta. Así que pensé en publicar aquí la respuesta completa en caso de que alguien tenga los mismos requisitos.
El código a continuación se puede usar en la parte superior de un script de Powershell para tener 4 parámetros opcionales de los cuales LaunchAsAdmin y LaunchAsCouponBrowser son mutuamente exclusivos, mientras que token y WorkstationName también son opcionales, pero se pueden combinar con cualquier otro parámetro.
[CmdletBinding(DefaultParametersetName="default")]
Param(
[string]$token,
[string]$WorkstationName,
[parameter(ParameterSetName="seta")][switch]$LaunchAsAdmin,
[parameter(ParameterSetName="setb")][switch]$LaunchAsCouponBrowser
)