July 31, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Constructing your First PowerShell Provider

  • October 23, 2009
  • By Jeffrey Juday
  • Send Email »
  • More Articles »

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



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel