Normally parameters for a Cmdlet are defined directly as properties on the Cmdlet class itself. There are a few other ways for a Cmdlet to define parameters, and in this short series of three parts, I’ll cover the three variants you’ll likely to encounter as you become a more experienced PowerShell developer. First thing you need to do is to implement the System.Management.Automation.IDynamicParameters interface on your Cmdlet. This interface has one member, GetDynamicParameters. This interface can be implemented on either a Provider or a Cmdlet. In the former case, a provider is able to add new parameters at runtime to certain built-in Cmdlets like Get-ChildItem, Get-Item & Get-ItemProperty. It is typically used in a path context-aware manner – e.g. depending on whether the current argument is a folder or item, and what Type such a folder or item might be. We’re just to cover the Cmdlet variant in this post.
My example is just a simple Cmdlet named Get-OSVersion. It writes out Environment.OSVersion to the pipeline, and will dynamically add a parameter. It adds –EnsureElevated if you’re running Vista or higher, otherwise it will add –EnsureAdministrator. Statically defined dynamic parameter sets are defined by creating a simple class and decorating that class with parameter/properties you want to surface as if that class was the Cmdlet itself, then returning it from the GetDynamicProperties method at runtime. Simple!
- [Cmdlet(VerbsCommon.Get, "OSVersion")]
- public class GetOSVersionCommand : PSCmdlet, IDynamicParameters
- {
- private const string SWITCH_VISTA = "EnsureElevated";
- private const string SWITCH_WINXP = "EnsureAdministrator";
-
- protected override void EndProcessing()
- {
- WriteObject(Environment.OSVersion);
-
- string switchName = IsVistaOrHigher() ?
- SWITCH_VISTA : SWITCH_WINXP;
-
-
- WriteWarning(String.Format("{0}.IsPresent {1}",
- switchName, IsSwitchPresent(switchName)));
- }
-
-
- public object GetDynamicParameters()
- {
- if (IsVistaOrHigher())
- {
- return new VistaParameters();
- }
- else
- {
- return new WinXPParameters();
- }
- }
-
- private bool IsSwitchPresent(string name)
- {
-
- Dictionary<string, object> parameters = MyInvocation.BoundParameters;
-
-
- if (parameters.ContainsKey(name))
- {
- return ((SwitchParameter) parameters[name]).IsPresent;
- }
- return false;
- }
-
- private static bool IsVistaOrHigher()
- {
- return (Environment.OSVersion.Version.Major >= 6);
- }
-
-
- internal class VistaParameters
- {
- [Parameter]
- public SwitchParameter EnsureElevated
- {
- get; set;
- }
- }
-
-
-
- internal class WinXPParameters
- {
- [Parameter]
- public SwitchParameter EnsureAdministrator
- {
- get; set;
- }
- }
- }
Of course, adding Dynamic Parameters is no good if you don’t know how to read them back. In the code, you can see I’m using MyInvocation.BoundParameters to check if the Switches have been set.