Compartir a través de


Creando un proveedor de contenedores para Windows PowerShell

Este tema describe cómo crear un proveedor de PowerShell para Windows que pueda funcionar en almacenes de datos multicapa. Para este tipo de almacén de datos, el nivel superior contiene los elementos raíz y cada nivel posterior se denomina nodo de elementos hijos. Al permitir que el usuario trabaje en estos nodos hijos, el usuario puede interactuar jerárquicamente a través del almacén de datos.

Los proveedores que pueden trabajar en almacenes de datos multinivel se denominan proveedores de contenedores Windows PowerShell. Sin embargo, ten en cuenta que un proveedor de contenedores PowerShell de Windows solo puede usarse cuando hay un contenedor (sin contenedores anidados) con elementos dentro. Si hay contenedores anidados, entonces debes implementar un proveedor de navegación PowerShell para Windows. Para más información sobre cómo implementar un proveedor de navegación Windows PowerShell, consulte Creación de un proveedor de navegación Windows PowerShell.

Nota:

Puedes descargar el archivo fuente (AccessDBSampleProvider04.cs) de C# para este proveedor utilizando el Microsoft Windows Software Development Kit para Windows Vista y los componentes de ejecución de .NET Framework 3.0. Para las instrucciones de descarga, consulta Cómo instalar Windows PowerShell y descargar el SDK de Windows PowerShell. Los archivos fuente descargados están disponibles en el <directorio de Ejemplos> de PowerShell. Para más información sobre otras implementaciones de proveedores de Windows PowerShell, consulte Diseñando su proveedor de PowerShell para Windows.

El proveedor de contenedores de Windows PowerShell descrito aquí define la base de datos como su único contenedor, con las tablas y filas de la base de datos definidas como elementos del contenedor.

Precaución

Ten en cuenta que este diseño asume una base de datos que tiene un campo con el ID del nombre, y que el tipo del campo es LongInteger.

Definiendo una clase de proveedor de contenedores para Windows PowerShell

Un proveedor de contenedores PowerShell para Windows debe definir una clase .NET que derive de la clase base System.Management.Automation.Provider.ContainerCmdletProvider . Aquí está la definición de clase para el proveedor de contenedores PowerShell de Windows descrito en esta sección.

[CmdletProvider("AccessDB", ProviderCapabilities.None)]
public class AccessDBProvider : ContainerCmdletProvider

Observa que en esta definición de clase, el atributo System.Management.Automation.Provider.CmdletProviderAttribute incluye dos parámetros. El primer parámetro especifica un nombre fácil de usar para el proveedor que utiliza Windows PowerShell. El segundo parámetro especifica las capacidades específicas de PowerShell de Windows que el proveedor expone al entorno de ejecución de Windows PowerShell durante el procesamiento de comandos. Para este proveedor, no se añaden capacidades específicas de PowerShell de Windows.

Definición de la funcionalidad base

Como se describe en Designing Your Windows PowerShell Provider, la clase System.Management.Automation.Provider.ContainerCmdletProvider deriva de varias otras clases que ofrecían diferentes funcionalidades de proveedores. Por tanto, un proveedor de contenedores Windows PowerShell necesita definir toda la funcionalidad proporcionada por esas clases.

Para implementar funcionalidades para añadir información de inicialización específica de la sesión y para liberar recursos que utiliza el proveedor, véase Creación de un proveedor básico de PowerShell para Windows. Sin embargo, la mayoría de los proveedores (incluido el que se describe aquí) pueden utilizar la implementación predeterminada de esta funcionalidad que ofrece Windows PowerShell.

Para acceder al almacén de datos, el proveedor debe implementar los métodos de la clase base System.Management.Automation.Provider.DriveCmdletProvider . Para más información sobre cómo implementar estos métodos, consulte Creación de un proveedor de unidades PowerShell para Windows.

Para manipular los elementos de un almacén de datos, como obtener, configurar y compensar elementos, el proveedor debe implementar los métodos proporcionados por la clase base System.Management.Automation.Provider.ItemCmdletProvider . Para más información sobre cómo implementar estos métodos, consulte Creación de un proveedor de elementos para Windows PowerShell.

Recuperación de objetos infantiles

Para recuperar un elemento hijo, el proveedor de contenedores PowerShell de Windows debe sobrescribir el método System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* para soportar llamadas desde el Get-ChildItem cmdlet. Este método recupera los elementos hijos del almacén de datos y los escribe en la tubería como objetos. Si se especifica el recurse parámetro del cmdlet, el método recupera a todos los hijos independientemente del nivel en el que se encuentren. Si el recurse parámetro no está especificado, el método recupera solo un nivel de hijos.

Aquí está la implementación del método System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* para este proveedor. Observa que este método recupera los elementos hijos en todas las tablas de la base de datos cuando la ruta indica la base de datos Access, y recupera los elementos hijos de las filas de esa tabla si la ruta indica una tabla de datos.

protected override void GetChildItems(string path, bool recurse)
{
    // If path represented is a drive then the children in the path are 
    // tables. Hence all tables in the drive represented will have to be
    // returned
    if (PathIsDrive(path))
    {
        foreach (DatabaseTableInfo table in GetTables())
        {
            WriteItemObject(table, path, true);

            // if the specified item exists and recurse has been set then 
            // all child items within it have to be obtained as well
            if (ItemExists(path) && recurse)
            {
                GetChildItems(path + pathSeparator + table.Name, recurse);
            }
        } // foreach (DatabaseTableInfo...
    } // if (PathIsDrive...
    else
    {
        // Get the table name, row number and type of path from the
        // path specified
        string tableName;
        int rowNumber;

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

        if (type == PathType.Table)
        {
            // Obtain all the rows within the table
            foreach (DatabaseRowInfo row in GetRows(tableName))
            {
                WriteItemObject(row, path + pathSeparator + row.RowNumber,
                        false);
            } // foreach (DatabaseRowInfo...
        }
        else if (type == PathType.Row)
        {
            // In this case the user has directly specified a row, hence
            // just give that particular row
            DatabaseRowInfo row = GetRow(tableName, rowNumber);
            WriteItemObject(row, path + pathSeparator + row.RowNumber,
                        false);
        }
        else
        {
            // In this case, the path specified is not valid
            ThrowTerminatingInvalidPathException(path);
        }
    } // else
} // GetChildItems

Cosas a recordar sobre la implementación de GetChildItems

Las siguientes condiciones pueden aplicarse a tu implementación de System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems*:

Adjuntar parámetros dinámicos al Get-ChildItem cmdlet

A veces, el Get-ChildItem cmdlet que llama a System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* requiere parámetros adicionales que se especifican dinámicamente en tiempo de ejecución. Para proporcionar estos parámetros dinámicos, el proveedor de contenedores PowerShell de Windows debe implementar el método System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItemsDynamicParameters* . Este método recupera parámetros dinámicos para el elemento en la ruta indicada y devuelve un objeto que tiene propiedades y campos con atributos de análisis similar a una clase cmdlet o un objeto System.Management.Automation.RuntimeDefinedParameterDictionary . El entorno de ejecución de Windows PowerShell utiliza el objeto devuelto para añadir los parámetros al Get-ChildItem cmdlet.

Este proveedor de contenedores de Windows PowerShell no implementa este método. Sin embargo, el siguiente código es la implementación predeterminada de este método.

Recuperación de nombres de objetos hijos

Para recuperar los nombres de los elementos hijos, el proveedor del contenedor PowerShell de Windows debe sobrescribir el método System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNames* para soportar llamadas desde el Get-ChildItem cmdlet cuando se especifica su Name parámetro. Este método recupera los nombres de los elementos hijos para la ruta especificada o los nombres de los elementos hijos para todos los contenedores si se especifica el returnAllContainers parámetro del cmdlet. Un nombre de hijo es la parte de hoja de un camino. Por ejemplo, el nombre hijo del camino C:\windows\system32\abc.dll es "abc.dll". El nombre hijo del directorio C:\windows\system32 es "system32".

Aquí está la implementación del método System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNames* para este proveedor. Observa que el método recupera nombres de tablas si la ruta especificada indica la base de datos de acceso (disco) y números de fila si la ruta indica una tabla.

protected override void GetChildNames(string path,
                              ReturnContainers returnContainers)
{
    // If the path represented is a drive, then the child items are
    // tables. get the names of all the tables in the drive.
    if (PathIsDrive(path))
    {
        foreach (DatabaseTableInfo table in GetTables())
        {
            WriteItemObject(table.Name, path, true);
        } // foreach (DatabaseTableInfo...
    } // if (PathIsDrive...
    else
    {
        // Get type, table name and row number from path specified
        string tableName;
        int rowNumber;

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

        if (type == PathType.Table)
        {
            // Get all the rows in the table and then write out the 
            // row numbers.
            foreach (DatabaseRowInfo row in GetRows(tableName))
            {
                WriteItemObject(row.RowNumber, path, false);
            } // foreach (DatabaseRowInfo...
        }
        else if (type == PathType.Row)
        {
            // In this case the user has directly specified a row, hence
            // just give that particular row
            DatabaseRowInfo row = GetRow(tableName, rowNumber);

            WriteItemObject(row.RowNumber, path, false);
        }
        else
        {
            ThrowTerminatingInvalidPathException(path);
        }
    } // else
} // GetChildNames

Cosas a recordar sobre la implementación de GetChildNames

Las siguientes condiciones pueden aplicarse a tu implementación de System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems*:

Adjuntar parámetros dinámicos al cmdlet de Get-ChildItem (nombre)

A veces, el Get-ChildItem cmdlet (con el Name parámetro) requiere parámetros adicionales que se especifican dinámicamente en tiempo de ejecución. Para proporcionar estos parámetros dinámicos, el proveedor de contenedores de Windows PowerShell debe implementar el método System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNamesDynamicParameters* . Este método recupera los parámetros dinámicos del elemento en la ruta indicada y devuelve un objeto que tiene propiedades y campos con atributos de análisis similar a una clase cmdlet o un objeto System.Management.Automation.RuntimeDefinedParameterDictionary . El entorno de ejecución de Windows PowerShell utiliza el objeto devuelto para añadir los parámetros al Get-ChildItem cmdlet.

Este proveedor no implementa este método. Sin embargo, el siguiente código es la implementación predeterminada de este método.

Renombramiento de los elementos

Para renombrar un elemento, un proveedor de contenedores de Windows PowerShell debe sobrescribir el método System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem* para soportar llamadas desde el Rename-Item cmdlet. Este método cambia el nombre del elemento en la ruta especificada al nuevo nombre proporcionado. El nuevo nombre debe ser siempre relativo al elemento principal (contenedor).

Este proveedor no anula el método System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem* . Sin embargo, la siguiente es la implementación predeterminada.

Cosas a recordar sobre la implementación de RenameItem

Las siguientes condiciones pueden aplicarse a tu implementación de System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem*:

Adjuntar parámetros dinámicos al Rename-Item cmdlet

A veces el Rename-Item cmdlet requiere parámetros adicionales que se especifican dinámicamente en tiempo de ejecución. Para proporcionar estos parámetros dinámicos, el proveedor de contenedores de Windows PowerShell debe implementar el método System.Management.Automation.Provider.ContainerCmdletProvider.RenameItemDynamicParameters* . Este método recupera los parámetros del elemento en la ruta indicada y devuelve un objeto que tiene propiedades y campos con atributos de análisis similar a una clase cmdlet o un objeto System.Management.Automation.RuntimeDefinedParameterDictionary . El entorno de ejecución de Windows PowerShell utiliza el objeto devuelto para añadir los parámetros al Rename-Item cmdlet.

Este proveedor de contenedores no implementa este método. Sin embargo, el siguiente código es la implementación predeterminada de este método.

Creación de nuevos objetos

Para crear nuevos elementos, un proveedor de contenedores debe implementar el método System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* para soportar llamadas desde el New-Item cmdlet. Este método crea un elemento de datos ubicado en la ruta especificada. El type parámetro del cmdlet contiene el tipo definido por el proveedor para el nuevo elemento. Por ejemplo, el proveedor del Sistema de Archivos utiliza un type parámetro con el valor de "archivo" o "directorio". El newItemValue parámetro del cmdlet especifica un valor específico del proveedor para el nuevo elemento.

Aquí está la implementación del método System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* para este proveedor.

protected override void NewItem( string path, string type, object newItemValue )
{
    // Create the new item here after
    // performing necessary validations
    //
    // WriteItemObject(newItemValue, path, false);

    // Example
    //
    // if (ShouldProcess(path, "new item"))
    // {
    //      // Create a new item and then call WriteObject
    //      WriteObject(newItemValue, path, false);
    // }

} // NewItem
{
    case 1:
        {
            string name = pathChunks[0];

            if (TableNameIsValid(name))
            {
                tableName = name;
                retVal = PathType.Table;
            }
        }
        break;

    case 2:
        {
            string name = pathChunks[0];

Cosas a recordar sobre la implementación de NewItem

Las siguientes condiciones pueden aplicarse a tu implementación de System.Management.Automation.Provider.ContainerCmdletProvider.NewItem*:

Adjuntar parámetros dinámicos al New-Item cmdlet

A veces el New-Item cmdlet requiere parámetros adicionales que se especifican dinámicamente en tiempo de ejecución. Para proporcionar estos parámetros dinámicos, el proveedor del contenedor debe implementar el método System.Management.Automation.Provider.ContainerCmdletProvider.NewItemDynamicParameters* . Este método recupera los parámetros del elemento en la ruta indicada y devuelve un objeto que tiene propiedades y campos con atributos de análisis similar a una clase cmdlet o un objeto System.Management.Automation.RuntimeDefinedParameterDictionary . El entorno de ejecución de Windows PowerShell utiliza el objeto devuelto para añadir los parámetros al New-Item cmdlet.

Este proveedor no implementa este método. Sin embargo, el siguiente código es la implementación predeterminada de este método.

Eliminación de objetos

Para eliminar elementos, el proveedor de PowerShell de Windows debe sobrescribir el método System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItem* para soportar llamadas desde el Remove-Item cmdlet. Este método elimina un elemento del almacenamiento de datos en la ruta especificada. Si el recurse parámetro del Remove-Item cmdlet está establecido en true, el método elimina todos los elementos hijos independientemente de su nivel. Si el parámetro está establecido en false, el método elimina solo un elemento en la ruta especificada.

Este proveedor no admite la retirada de objetos. Sin embargo, el siguiente código es la implementación predeterminada de System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItem*.

Cosas a recordar sobre la implementación de RemoveItem

Las siguientes condiciones pueden aplicarse a tu implementación de System.Management.Automation.Provider.ContainerCmdletProvider.NewItem*:

Adjuntar parámetros dinámicos al Remove-Item cmdlet

A veces el Remove-Item cmdlet requiere parámetros adicionales que se especifican dinámicamente en tiempo de ejecución. Para proporcionar estos parámetros dinámicos, el proveedor del contenedor debe implementar el método System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItemDynamicParameters* para gestionar estos parámetros. Este método recupera los parámetros dinámicos del elemento en la ruta indicada y devuelve un objeto que tiene propiedades y campos con atributos de análisis similar a una clase cmdlet o un objeto System.Management.Automation.RuntimeDefinedParameterDictionary . El entorno de ejecución de Windows PowerShell utiliza el objeto devuelto para añadir los parámetros al Remove-Item cmdlet.

Este proveedor de contenedores no implementa este método. Sin embargo, el siguiente código es la implementación predeterminada de System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItemDynamicParameters*.

Consulta de elementos secundarios

Para comprobar si existen elementos hijos en la ruta especificada, el proveedor de contenedores de Windows PowerShell debe anular el método System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems* . Este método se devuelve true si el artículo tiene hijos, y false en otros casos. Para un camino nulo o vacío, el método considera cualquier elemento en el almacenamiento de datos como hijos y devuelve true.

Aquí está la anulación para el método System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems* . Si hay más de dos partes de camino creadas por el método asistente ChunkPath, el método devuelve false, ya que solo se definen un contenedor de base de datos y un contenedor de tabla. Para más información sobre este método auxiliar, consulta el método ChunkPath que se explica en Creando un proveedor de elementos para Windows PowerShell.

protected override bool HasChildItems( string path )
{
    return false;
} // HasChildItems
        ErrorCategory.InvalidOperation, tableName));
}

return results;

Cosas a recordar sobre la implementación de HasChildItems

Las siguientes condiciones pueden aplicarse a tu implementación de System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems*:

Copia de elementos

Para copiar elementos, el proveedor del contenedor debe implementar el método System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem para soportar llamadas desde el Copy-Item cmdlet. Este método copia un elemento de datos desde la ubicación indicada por el path parámetro del cmdlet a la ubicación indicada por el copyPath parámetro. Si se especifica el recurse parámetro, el método copia todos los subcontenedores. Si el parámetro no se especifica, el método copia solo un nivel de elementos.

Este proveedor no implementa este método. Sin embargo, el siguiente código es la implementación predeterminada de System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem.

Cosas a recordar sobre la implementación de CopyItem

Las siguientes condiciones pueden aplicarse a tu implementación de System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem:

Adjuntar parámetros dinámicos al Copy-Item cmdlet

A veces el Copy-Item cmdlet requiere parámetros adicionales que se especifican dinámicamente en tiempo de ejecución. Para proporcionar estos parámetros dinámicos, el proveedor de contenedores de Windows PowerShell debe implementar el método System.Management.Automation.Provider.ContainerCmdletProvider.CopyItemDynamicParameters* para gestionar estos parámetros. Este método recupera los parámetros del elemento en la ruta indicada y devuelve un objeto que tiene propiedades y campos con atributos de análisis similar a una clase cmdlet o un objeto System.Management.Automation.RuntimeDefinedParameterDictionary . El entorno de ejecución de Windows PowerShell utiliza el objeto devuelto para añadir los parámetros al Copy-Item cmdlet.

Este proveedor no implementa este método. Sin embargo, el siguiente código es la implementación predeterminada de System.Management.Automation.Provider.ContainerCmdletProvider.CopyItemDynamicParameters*.

Ejemplo de código

Para ver el código de muestra completo, consulte AccessDbProviderSample04 Code Sample.

Construyendo el proveedor de PowerShell de Windows

Consulta cómo registrar cmdlets, proveedores y aplicaciones anfitrionas.

Probando el proveedor PowerShell de Windows

Cuando tu proveedor de PowerShell de Windows esté registrado en Windows PowerShell, puedes probarlo ejecutando los cmdlets compatibles en la línea de comandos. Ten en cuenta que el siguiente ejemplo de salida utiliza una base de datos ficticia de Access.

  1. Ejecuta el Get-ChildItem cmdlet para recuperar la lista de elementos hijos de una tabla Clientes en la base de datos de Access.

    Get-ChildItem mydb:customers
    

    Aparece la siguiente salida.

    PSPath        : AccessDB::customers
    PSDrive       : mydb
    PSProvider    : System.Management.Automation.ProviderInfo
    PSIsContainer : True
    Data          : System.Data.DataRow
    Name          : Customers
    RowCount      : 91
    Columns       :
    
  2. Ejecuta el Get-ChildItem cmdlet de nuevo para recuperar los datos de una tabla.

    (Get-ChildItem mydb:customers).Data
    

    Aparece la siguiente salida.

    TABLE_CAT   : C:\PS\northwind
    TABLE_SCHEM :
    TABLE_NAME  : Customers
    TABLE_TYPE  : TABLE
    REMARKS     :
    
  3. Ahora usa el Get-Item cmdlet para recuperar los elementos en la fila 0 de la tabla de datos.

    Get-Item mydb:\customers\0
    

    Aparece la siguiente salida.

    PSPath        : AccessDB::customers\0
    PSDrive       : mydb
    PSProvider    : System.Management.Automation.ProviderInfo
    PSIsContainer : False
    Data          : System.Data.DataRow
    RowNumber     : 0
    
  4. Reutilizar Get-Item para recuperar los datos de los elementos de la fila 0.

    (Get-Item mydb:\customers\0).Data
    

    Aparece la siguiente salida.

    CustomerID   : 1234
    CompanyName  : Fabrikam
    ContactName  : Eric Gruber
    ContactTitle : President
    Address      : 4567 Main Street
    City         : Buffalo
    Region       : NY
    PostalCode   : 98052
    Country      : USA
    Phone        : (425) 555-0100
    Fax          : (425) 555-0101
    
  5. Ahora usa el New-Item cmdlet para añadir una fila a una tabla existente. El Path parámetro especifica el camino completo hasta la fila y debe indicar un número de fila mayor que el número existente de filas en la tabla. El Type parámetro indica Row especificar qué tipo de elemento añadir. Finalmente, el Value parámetro especifica una lista delimitada por comas de valores de columna para la fila.

    New-Item -Path mydb:\Customers\3 -ItemType "Row" -Value "3,CustomerFirstName,CustomerLastName,CustomerEmailAddress,CustomerTitle,CustomerCompany,CustomerPhone, CustomerAddress,CustomerCity,CustomerState,CustomerZip,CustomerCountry"
    
  6. Verifica la corrección de la operación del nuevo elemento de la siguiente manera.

    PS mydb:\> cd Customers
    PS mydb:\Customers> (Get-Item 3).Data
    

    Aparece la siguiente salida.

    ID        : 3
    FirstName : Eric
    LastName  : Gruber
    Email     : ericgruber@fabrikam.com
    Title     : President
    Company   : Fabrikam
    WorkPhone : (425) 555-0100
    Address   : 4567 Main Street
    City      : Buffalo
    State     : NY
    Zip       : 98052
    Country   : USA
    

Véase también

Creación de proveedores PowerShell para Windows

Diseñando tu proveedor de PowerShell para Windows

Implementando un Proveedor PowerShell de Windows

Implementando un proveedor de PowerShell para Windows para navegación

Cómo registrar comandantes, proveedores y aplicaciones anfitrionas

Windows PowerShell SDK

Guía del programador de PowerShell para Windows