Constructing your First PowerShell Provider
Navigation and Dynamic Parameters
One interesting PowerShell Provider feature is Dynamic
Parameters. If you peruse the
NavigationCmdLetProvider
object in the object
model viewer, you'll notice a
"DynamicParameter
" function for almost every
standard override function. DynamicParameters
allow a developer to extend the number of parameters for the
standard CmdLets. For example, normally if you want to
invoke the New-Item Cmdlet the data is supplied in the -
value parameter separated by commas like in the example
below.
New-Item -value one, two, three
DynamicParameters allow a developer to create named parameters rather than a series of values separated by commas. So, you can invoke the New-Item CmdLet on the sample with the following PowerShell code.
New-Item -MyParameter1 one -MyParameter2 two
Below is the NewItemDynamicParamer
function
followed by the NewItem function.
protected override void NewItem(string path, string itemTypeName, object newItemValue) { TraceTestPSOut("BEGIN NewItem"); if (newItemValue == null) { TraceTestPSOut("newItemValue is NULL"); } else { TraceTestPSOut(path + " itemTypeName " + itemTypeName + " value " + newItemValue.ToString()); object[] parms = (object[])newItemValue; foreach (object obj in parms) { TraceTestPSOut("Obj " + obj.GetType().ToString() + " " + obj.ToString()); } } if (this.DynamicParameters == null) { TraceTestPSOut("DynamicParameters == NULL"); } else { foreach (RuntimeDefinedParameter objParm in ((RuntimeDefinedParameterDictionary)this.DynamicParameters).Values) { TraceTestPSOut(" RunTimeDefinedParm " + objParm.Name + " " + objParm.Value.ToString()); } } TraceTestPSOut("END NewItem"); } protected override object NewItemDynamicParameters(string path, string itemTypeName, object newItemValue) { TraceTestPSOut("BEGIN NewItemDynamicParameters"); RuntimeDefinedParameterDictionary dic = new RuntimeDefinedParameterDictionary(); ParameterAttribute attrib = null; Collection<ATTRIBUTE> col = null; RuntimeDefinedParameter runDefParm = null; attrib = new ParameterAttribute(); attrib.ParameterSetName = "MyParameters"; attrib.Mandatory = false; attrib.ValueFromPipeline = false; col = new Collection<ATTRIBUTE>(); col.Add(attrib); runDefParm = new RuntimeDefinedParameter("MyParameter1", typeof(string), col); dic.Add("MyParameter1", runDefParm); runDefParm = new RuntimeDefinedParameter("MyParameter2", typeof(string), col); dic.Add("MyParameter2", runDefParm); TraceTestPSOut("END NewItemDynamicParameters"); return dic; }
Because I chose to accept how PowerShell handles general path validation in a Provider, there was not much to I needed to override in the Navigation region of the sample.
That covers all the Provider functions. There is some needed code though to get the sample to work in PowerShell.
Attributes and Installation
To load your Provider you need a PSSnapIn class. Here is the TestPSProviderPSSnapIn class from the sample.
[RunInstaller(true)] public class TestPSProviderPSSnapIn : PSSnapIn { /// <SUMMARY> /// Create an instance of the TestPSProviderPSSnapIn /// </SUMMARY> public TestPSProviderPSSnapIn() : base() { }
Other than providing some naming properties there is not
much to change in this class. Note however, the
Installer
Attribute and the
System.Configuration.Install
assembly reference
is necessary to enable InstallUtil.exe
functionality.
The PowerShell code below loads the SnapIn
and installs the Provider. It's been configured to run the
64 bit version of InstallUtil
.
$path = Resolve-Path "C:\articles and presentations\PowerShell\PowerShell\Testing.PowerShell.Basics\bin\Debug\Testing.PowerShell.Basics.dll" $register = "$env:windir/Microsoft.NET/Framework64/v2.0.50727/installutil" & $register $path add-PSSnapin TestPSProviderPSSnapIn set-location TestPS:\Container
Conclusion
A PowerShell Provider is a lot like the database of a PowerShell solution. Standard CmdLets act on the Provider, adding, removing, and reading data stored in the Provider. To understand how to build a Provider, a developer must understand how, when, and where .NET Provider code gets executed. This article and the accompanying sample code demonstrates .NET code execution in a Navigation Provider.
Resources
Designing Your Windows PowerShell Provider
How to Create a Windows PowerShell Provider
Windows PowerShell Blog
Windows PowerShell Getting Started Guide
DebugView
Page 3 of 3
This article was originally published on October 23, 2009