Skip to content

Instantly share code, notes, and snippets.

@fearthecowboy
Created October 21, 2014 15:52
Show Gist options
  • Save fearthecowboy/07a686a5a09fbd26571d to your computer and use it in GitHub Desktop.
Save fearthecowboy/07a686a5a09fbd26571d to your computer and use it in GitHub Desktop.
Modifying the validation set for a compile-time powershell parameter
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Management.Automation;
using System.Reflection;
using System.Threading;
namespace parametertest
{
[Cmdlet("Test", "This")]
public class TestThis : PSCmdlet, IDynamicParameters
{
protected static ManualResetEvent _reentrancyLock = new ManualResetEvent(false);
private static readonly FieldInfo ValidValues = typeof (ValidateSetAttribute).GetField("validValues",
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
private RuntimeDefinedParameterDictionary _dynamicParameters;
[Parameter, ValidateSet("not-used")]
public string Source { get; set; }
public object GetDynamicParameters()
{
if (!_reentrancyLock.WaitOne(0))
{
// we use this because PowerShell will create more instances of the cmdlet (and/or call this same function
// again) when we access MyInvocation.MyCommand.Parameters
_reentrancyLock.Set();
#if! DUMP_DEBUG
// Note1 : tangential thing:
// you can see what cmdlet parameters are defined -- both dynamic and static
// you'll note that you will actually see the dynamic parameters in this list
// that get defined after. Creepy, eh?
foreach (var k in this.MyInvocation.MyCommand.Parameters.Keys)
{
Console.WriteLine(k);
}
#endif
// this call must be done when we have the _reentrancy lock on:
SetValidationSetValues("Source", new[] {"any", "set", "of", "values"});
// we're done our dark magic.
_reentrancyLock.Reset();
}
// an example of every-day-normal dynamic parameters:
// not-important to the solution, just demonstrates
// that we can see *defintions* of dynamic parameters during
// dynamic parameter generation (
_dynamicParameters = new RuntimeDefinedParameterDictionary();
_dynamicParameters.Add("Color",
new RuntimeDefinedParameter("Color", typeof (string),
new Collection<Attribute>
{
new ParameterAttribute(),
new ValidateSetAttribute(new[] {"red", "green", "blue"})
}));
_dynamicParameters.Add("Flavor",
new RuntimeDefinedParameter("Flavor", typeof (string),
new Collection<Attribute>
{
new ParameterAttribute(),
new ValidateSetAttribute(new[] {"chocolate", "vanilla", "strawberry"})
}));
return _dynamicParameters;
}
private void SetValidationSetValues(string parameterName, IEnumerable<string> values)
{
if (MyInvocation.MyCommand.Parameters.ContainsKey(parameterName))
{
var attribute =
MyInvocation.MyCommand.Parameters[parameterName].Attributes.FirstOrDefault(
each => each is ValidateSetAttribute) as ValidateSetAttribute;
if (attribute != null)
{
ValidValues.SetValue(attribute, values.ToArray());
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment