March 5, 2021
Hot Topics:

Constructing your First PowerShell Provider

  • By Jeffrey Juday
  • Send Email »
  • More Articles »

Getting Started and Drive

Like all .NET development PowerShell development starts with referencing a set of assemblies. System.Management.Automation contains most of what you'll need for building PowerShell components. System.Configuration.Install is another useful assembly I'll discuss later in the article.

In the sample, the Provider is implemented in the TestPSProvider class. As I stated earlier, I'm implementing a Navigation Provider so the base class inherits from NavigationCmdLetProvider. Aside from selecting a Provider base class, a Provider class requires the CmdLetProvider attribute. Below is the Provider class definition.

[CmdletProvider("TestPSProvider", ProviderCapabilities.None)]
public class TestPSProvider : NavigationCmdletProvider

PowerShell Provider state is stored in a Drive. Drives typically inherit from PSDriveInfo. The sample Drive class is called TestDriveInfo. The TestDriveInfo class appears below.

  internal class TestDriveInfo : PSDriveInfo
      private TraceTest _trace = new TraceTest("PS");
      public TraceTest TraceMessage
          get { return _trace; }
      public TestDriveInfo(PSDriveInfo driveInfo)
          : base(driveInfo)
          string somethingToSave = "";
          somethingToSave = "Something";
          _trace.WriteLine("PSDriveInfo " + driveInfo.Description + " " + driveInfo.Root + " " + driveInfo.Name + " " + driveInfo.Provider.Name + " " + driveInfo.Provider.Description);
          this.SomethingToSave = somethingToSave;            
      public string SomethingToSave { get; protected set; }

Aside from storing state, the Drive can be considered the root of a Path. Drive naming choices appear in PowerShell. To create drives, a PowerShell Provider must override InitializeDefaultDrives, the function appearing below.

  protected override System.Collections.ObjectModel.Collection<PSDRIVEINFO> InitializeDefaultDrives()
      System.Collections.ObjectModel.Collection<PSDRIVEINFO> col = new System.Collections.ObjectModel.Collection<PSDRIVEINFO>();
      TraceTestPSOut("BEGIN InitializeDefaultDrives");
      PSDriveInfo info = new PSDriveInfo("TestPS", this.ProviderInfo, _pathSeparator, "Default Root", PSCredential.Empty);
      TraceTestPSOut("END InitializeDefaultDrives");
      return col;

Most of the really interesting parts of a PowerShell Provider relate to the "item" CmdLets. Item CmdLet processing is handled in the sample code by the functions in the Item and Container regions.

Item and Container

Run the "get-command" Cmdlet and you'll notice a lot of CmdLets ending in "-Item", a few examples are: New-Item, Copy-Item, and Clear-Item. Invoking these CmdLets changes data in the Provider calling similarly named functions among the Item and Container Regions in the Sample application. An annotated view of the Item and Container regions appears below.

  protected override bool ItemExists(string path)
  protected override void ClearItem(string path)
  protected override void GetItem(string path)
  protected override void SetItem(string path, object value)
  protected override void CopyItem(string path, string copyPath, bool recurse)
  protected override void GetChildItems(string path, bool recurse)

Earlier I mentioned the hierarchy of Providers. The Item region corresponds with functions on the ItemCmdLetProvider and the Container region corresponds to the ContainerCmdLetProvider. The remaining functionality is supplied by the Navigation region functions. Before I cover Navigation I want to briefly touch on Dynamic Parameters.

Page 2 of 3

This article was originally published on October 23, 2009

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date