Creating a Windows PowerShell item provider

This topic describes how to create a Windows PowerShell provider that can manipulate the data in a data store. In this topic, the elements of data in the store are referred to as the "items" of the data store. As a consequence, a provider that can manipulate the data in the store is referred to as a Windows PowerShell item provider.

Note

You can download the C# source file (AccessDBSampleProvider03.cs) for this provider using the Microsoft Windows Software Development Kit for Windows Vista and .NET Framework 3.0 Runtime Components. For download instructions, see How to Install Windows PowerShell and Download the Windows PowerShell SDK. The downloaded source files are available in the PowerShell Samples directory. For more information about other Windows PowerShell provider implementations, see Designing Your Windows PowerShell Provider.

The Windows PowerShell item provider described in this topic gets items of data from an Access database. In this case, an "item" is either a table in the Access database or a row in a table.

Defining the Windows PowerShell item provider class

A Windows PowerShell item provider must define a .NET class that derives from the System.Management.Automation.Provider.ItemCmdletProvider base class. The following is the class definition for the item provider described in this section.

[CmdletProvider("AccessDB", ProviderCapabilities.None)]

public class AccessDBProvider : ItemCmdletProvider

Note that in this class definition, the System.Management.Automation.Provider.CmdletProviderAttribute attribute includes two parameters. The first parameter specifies a user-friendly name for the provider that is used by Windows PowerShell. The second parameter specifies the Windows PowerShell specific capabilities that the provider exposes to the Windows PowerShell runtime during command processing. For this provider, there are no added Windows PowerShell specific capabilities.

Defining base functionality

As described in Design Your Windows PowerShell Provider, the System.Management.Automation.Provider.DriveCmdletProvider class derives from several other classes that provided different provider functionality. A Windows PowerShell item provider, therefore, must define all of the functionality provided by those classes.

For more information about how to implement functionality for adding session-specific initialization information and for releasing resources used by the provider, see Creating a Basic Windows PowerShell Provider. However, most providers, including the provider described here, can use the default implementation of this functionality that is provided by Windows PowerShell.

Before the Windows PowerShell item provider can manipulate the items in the store, it must implement the methods of the System.Management.Automation.Provider.DriveCmdletProvider base class to access to the data store. For more information about implementing this class, see Creating a Windows PowerShell Drive Provider.

Checking for path validity

When looking for an item of data, the Windows PowerShell runtime furnishes a Windows PowerShell path to the provider, as defined in the "PSPath Concepts" section of How Windows PowerShell Works. A Windows PowerShell item provider must verify the syntactic and semantic validity of any path passed to it by implementing the System.Management.Automation.Provider.ItemCmdletProvider.IsValidPath method. This method returns true if the path is valid, and false otherwise. Be aware that the implementation of this method should not verify the existence of the item at the path, but only that the path is syntactically and semantically correct.

Here is the implementation of the System.Management.Automation.Provider.ItemCmdletProvider.IsValidPath method for this provider. Note that this implementation calls a NormalizePath helper method to convert all separators in the path to a uniform one.

protected override bool IsValidPath(string path)
{
    bool result = true;

    // check if the path is null or empty
    if (String.IsNullOrEmpty(path))
    {
        result = false;
    }

    // convert all separators in the path to a uniform one
    path = NormalizePath(path);

    // split the path into individual chunks
    string[] pathChunks = path.Split(pathSeparator.ToCharArray());

    foreach (string pathChunk in pathChunks)
    {
        if (pathChunk.Length == 0)
        {
            result = false;
        }
    }
    return result;
} // IsValidPath

Determining if an item exists

After verifying the path, the Windows PowerShell runtime must determine if an item of data exists at that path. To support this type of query, the Windows PowerShell item provider implements the System.Management.Automation.Provider.ItemCmdletProvider.ItemExists method. This method returns true an item is found at the specified path and false (default) otherwise.

Here is the implementation of the System.Management.Automation.Provider.ItemCmdletProvider.ItemExists method for this provider. Note that this method calls the PathIsDrive, ChunkPath, and GetTable helper methods, and uses a provider defined DatabaseTableInfo object.

protected override bool ItemExists(string path)
{
    // check if the path represented is a drive
    if (PathIsDrive(path))
    {
        return true;
    }

    // Obtain type, table name and row number from path
    string tableName;
    int rowNumber;

    PathType type = GetNamesFromPath(path, out tableName, out rowNumber);

    DatabaseTableInfo table = GetTable(tableName);

    if (type == PathType.Table)
    {
        // if specified path represents a table then DatabaseTableInfo
        // object for the same should exist
        if (table != null)
        {
            return true;
        }
    }
    else if (type == PathType.Row)
    {
        // if specified path represents a row then DatabaseTableInfo should
        // exist for the table and then specified row number must be within
        // the maximum row count in the table
        if (table != null && rowNumber < table.RowCount)
        {
            return true;
        }
    }

    return false;

} // ItemExists

Things to remember about implementing ItemExists

The following conditions may apply to your implementation of System.Management.Automation.Provider.ItemCmdletProvider.ItemExists:

Attaching dynamic parameters to the Test-Path cmdlet

Sometimes the Test-Path cmdlet that calls System.Management.Automation.Provider.ItemCmdletProvider.ItemExists requires additional parameters that are specified dynamically at runtime. To provide these dynamic parameters the Windows PowerShell item provider must implement the System.Management.Automation.Provider.ItemCmdletProvider.ItemExistsDynamicParameters method. This method retrieves the dynamic parameters for the item at the indicated path and returns an object that has properties and fields with parsing attributes similar to a cmdlet class or a System.Management.Automation.RuntimeDefinedParameterDictionary object. The Windows PowerShell runtime uses the returned object to add the parameters to the Test-Path cmdlet.

This Windows PowerShell item provider does not implement this method. However, the following code is the default implementation of this method.

Retrieving an item

To retrieve an item, the Windows PowerShell item provider must override System.Management.Automation.Provider.ItemCmdletProvider.GetItem method to support calls from the Get-Item cmdlet. This method writes the item using the System.Management.Automation.Provider.CmdletProvider.WriteItemObject method.

Here is the implementation of the System.Management.Automation.Provider.ItemCmdletProvider.GetItem method for this provider. Note that this method uses the GetTable and GetRow helper methods to retrieve items that are either tables in the Access database or rows in a data table.

protected override void GetItem(string path)
{
    // check if the path represented is a drive
    if (PathIsDrive(path))
    {
        WriteItemObject(this.PSDriveInfo, path, true);
        return;
    }// if (PathIsDrive...

     // Get table name and row information from the path and do 
     // necessary actions
     string tableName;
     int rowNumber;

     PathType type = GetNamesFromPath(path, out tableName, out rowNumber);

     if (type == PathType.Table)
     {
         DatabaseTableInfo table = GetTable(tableName);
         WriteItemObject(table, path, true);
     }
     else if (type == PathType.Row)
     {
         DatabaseRowInfo row = GetRow(tableName, rowNumber);
         WriteItemObject(row, path, false);
     }
     else
     {
         ThrowTerminatingInvalidPathException(path);
     }

 } // GetItem

Things to remember about implementing GetItem

The following conditions may apply to an implementation of System.Management.Automation.Provider.ItemCmdletProvider.GetItem:

Attaching dynamic parameters to the Get-Item cmdlet

Sometimes the Get-Item cmdlet requires additional parameters that are specified dynamically at runtime. To provide these dynamic parameters the Windows PowerShell item provider must implement the System.Management.Automation.Provider.ItemCmdletProvider.GetItemDynamicParameters method. This method retrieves the dynamic parameters for the item at the indicated path and returns an object that has properties and fields with parsing attributes similar to a cmdlet class or a System.Management.Automation.RuntimeDefinedParameterDictionary object. The Windows PowerShell runtime uses the returned object to add the parameters to the Get-Item cmdlet.

This provider does not implement this method. However, the following code is the default implementation of this method.

Setting an item

To set an item, the Windows PowerShell item provider must override the System.Management.Automation.Provider.ItemCmdletProvider.SetItem method to support calls from the Set-Item cmdlet. This method sets the value of the item at the specified path.

This provider does not provide an override for the System.Management.Automation.Provider.ItemCmdletProvider.SetItem method. However, the following is the default implementation of this method.

Things to remember about implementing SetItem

The following conditions may apply to your implementation of System.Management.Automation.Provider.ItemCmdletProvider.SetItem:

Retrieving dynamic parameters for SetItem

Sometimes the Set-Item cmdlet requires additional parameters that are specified dynamically at runtime. To provide these dynamic parameters the Windows PowerShell item provider must implement the System.Management.Automation.Provider.ItemCmdletProvider.SetItemDynamicParameters method. This method retrieves the dynamic parameters for the item at the indicated path and returns an object that has properties and fields with parsing attributes similar to a cmdlet class or a System.Management.Automation.RuntimeDefinedParameterDictionary object. The Windows PowerShell runtime uses the returned object to add the parameters to the Set-Item cmdlet.

This provider does not implement this method. However, the following code is the default implementation of this method.

Clearing an item

To clear an item, the Windows PowerShell item provider implements the System.Management.Automation.Provider.ItemCmdletProvider.ClearItem method to support calls from the Clear-Item cmdlet. This method erases the data item at the specified path.

This provider does not implement this method. However, the following code is the default implementation of this method.

Things to remember about implementing ClearItem

The following conditions may apply to an implementation of System.Management.Automation.Provider.ItemCmdletProvider.ClearItem:

Retrieve dynamic parameters for ClearItem

Sometimes the Clear-Item cmdlet requires additional parameters that are specified dynamically at runtime. To provide these dynamic parameters the Windows PowerShell item provider must implement the System.Management.Automation.Provider.ItemCmdletProvider.ClearItemDynamicParameters method. This method retrieves the dynamic parameters for the item at the indicated path and returns an object that has properties and fields with parsing attributes similar to a cmdlet class or a System.Management.Automation.RuntimeDefinedParameterDictionary object. The Windows PowerShell runtime uses the returned object to add the parameters to the Clear-Item cmdlet.

This item provider does not implement this method. However, the following code is the default implementation of this method.

Performing a default action for an item

A Windows PowerShell item provider can implement the System.Management.Automation.Provider.ItemCmdletProvider.InvokeDefaultAction method to support calls from the Invoke-Item cmdlet, which allows the provider to perform a default action for the item at the specified path. For example, the FileSystem provider might use this method to call ShellExecute for a specific item.

This provider does not implement this method. However, the following code is the default implementation of this method.

Things to remember about implementing InvokeDefaultAction

The following conditions may apply to an implementation of System.Management.Automation.Provider.ItemCmdletProvider.InvokeDefaultAction:

Retrieve dynamic parameters for InvokeDefaultAction

Sometimes the Invoke-Item cmdlet requires additional parameters that are specified dynamically at runtime. To provide these dynamic parameters the Windows PowerShell item provider must implement the System.Management.Automation.Provider.ItemCmdletProvider.InvokeDefaultActionDynamicParameters method. This method retrieves the dynamic parameters for the item at the indicated path and returns an object that has properties and fields with parsing attributes similar to a cmdlet class or a System.Management.Automation.RuntimeDefinedParameterDictionary object. The Windows PowerShell runtime uses the returned object to add the dynamic parameters to the Invoke-Item cmdlet.

This item provider does not implement this method. However, the following code is the default implementation of this method.

Implementing helper methods and classes

This item provider implements several helper methods and classes that are used by the public override methods defined by Windows PowerShell. The code for these helper methods and classes are shown in the Code Sample section.

NormalizePath method

This item provider implements a NormalizePath helper method to ensure that the path has a consistent format. The format specified uses a backslash (\) as a separator.

PathIsDrive method

This item provider implements a PathIsDrive helper method to determine if the specified path is actually the drive name.

ChunkPath method

This item provider implements a ChunkPath helper method that breaks up the specified path so that the provider can identify its individual elements. It returns an array composed of the path elements.

GetTable method

This item provider implements the GetTables helper method that returns a DatabaseTableInfo object that represents information about the table specified in the call.

GetRow method

The System.Management.Automation.Provider.ItemCmdletProvider.GetItem method of this item provider calls the GetRows helper method. This helper method retrieves a DatabaseRowInfo object that represents information about the specified row in the table.

DatabaseTableInfo class

This item provider defines a DatabaseTableInfo class that represents a collection of information in a data table in the database. This class is similar to the System.IO.Directoryinfo class.

The sample item provider defines a DatabaseTableInfo.GetTables method that returns a collection of table information objects defining the tables in the database. This method includes a try/catch block to ensure that any database error shows up as a row with zero entries.

DatabaseRowInfo class

This item provider defines the DatabaseRowInfo helper class that represents a row in a table of the database. This class is similar to the System.IO.FileInfo class.

The sample provider defines a DatabaseRowInfo.GetRows method to return a collection of row information objects for the specified table. This method includes a try/catch block to trap exceptions. Any errors will result in no row information.

Code sample

For complete sample code, see AccessDbProviderSample03 Code Sample.

Defining object types and formatting

When writing a provider, it may be necessary to add members to existing objects or define new objects. When finished, create a Types file that Windows PowerShell can use to identify the members of the object and a Format file that defines how the object is displayed. For more information, see Extending Object Types and Formatting.

Building the Windows PowerShell provider

See How to Register Cmdlets, Providers, and Host Applications.

Testing the Windows PowerShell provider

When this Windows PowerShell item provider is registered with Windows PowerShell, you can only test the basic and drive functionality of the provider. To test the manipulation of items, you must also implement container functionality described in Implementing a Container Windows PowerShell Provider.

See also