Búsqueda de sitios web

Crear un proveedor de contenido de Windows PowerShell


Este tema describe cómo crear un proveedor de Windows PowerShell que permita al usuario manipular el contenido de los elementos en un almacén de datos. Como consecuencia, un proveedor que puede manipular el contenido de los elementos se denomina proveedor de contenido de Windows PowerShell.

Nota

Puede descargar el archivo fuente de C# (AccessDBSampleProvider06.cs) para este proveedor utilizando el kit de desarrollo de software de Microsoft Windows para Windows Vista y .NET Framework 3.0 Runtime Components. Para obtener instrucciones de descarga, consulte Cómo instalar Windows PowerShell y descargar el SDK de Windows PowerShell. Los archivos fuente descargados están disponibles en el directorio . Para obtener más información sobre otras implementaciones de proveedores de Windows PowerShell, consulte Diseño de su proveedor de Windows PowerShell.

Definir la clase de proveedor de contenido de Windows PowerShell

Un proveedor de contenido de Windows PowerShell debe crear una clase .NET que admita la interfaz System.Management.Automation.Provider.Icontentcmdletprovider. Aquí está la definición de clase para el proveedor de elementos descrito en esta sección.

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

Tenga en cuenta 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 Windows PowerShell que el proveedor expone al tiempo de ejecución de Windows PowerShell durante el procesamiento de comandos. Para este proveedor, no hay capacidades específicas de Windows PowerShell agregadas.

Definir la funcionalidad de la clase base

Como se describe en Diseño de su proveedor de Windows PowerShell, la clase System.Management.Automation.Provider.Navigationcmdletprovider deriva de varias otras clases que proporcionaron una funcionalidad de proveedor diferente. Por lo tanto, un proveedor de contenido de Windows PowerShell normalmente define toda la funcionalidad proporcionada por esas clases.

Para obtener más información sobre cómo implementar la funcionalidad para agregar información de inicialización específica de la sesión y liberar recursos que utiliza el proveedor, consulte Creación de un proveedor básico de Windows PowerShell. Sin embargo, la mayoría de los proveedores, incluido el proveedor que se describe aquí, pueden usar la implementación predeterminada de esta funcionalidad proporcionada por 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 obtener más información sobre la implementación de estos métodos, consulte Creación de un proveedor de unidades de Windows PowerShell.

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

Para trabajar en almacenes de datos multicapa, el proveedor debe implementar los métodos proporcionados por la clase base System.Management.Automation.Provider.Containercmdletprovider. Para obtener más información sobre la implementación de estos métodos, consulte Creación de un proveedor de contenedores de Windows PowerShell.

Para admitir comandos recursivos, contenedores anidados y rutas relativas, el proveedor debe implementar la clase base System.Management.Automation.Provider.Navigationcmdletprovider. Además, este proveedor de contenido de Windows PowerShell puede adjuntar la interfaz System.Management.Automation.Provider.Icontentcmdletprovider a la clase base System.Management.Automation.Provider.Navigationcmdletprovider y, por lo tanto, debe implementar los métodos proporcionados por esa clase. Para obtener más información, consulte cómo implementar esos métodos, consulte Implementar un proveedor de navegación de Windows PowerShell.

Implementación de un lector de contenido

Para leer el contenido de un elemento, un proveedor debe implementar una clase de lector de contenido que derive de System.Management.Automation.Provider.Icontentreader. El lector de contenido de este proveedor permite el acceso al contenido de una fila en una tabla de datos. La clase de lector de contenido define un método Read que recupera los datos de la fila indicada y devuelve una lista que representa esos datos, un método Seek que mueve el lector de contenido, un Seek que mueve el lector de contenido, un Método >Close que cierra el lector de contenido y un método Dispose.

public class AccessDBContentReader : IContentReader
{
    // A provider instance is required so as to get "content"
    private AccessDBProvider provider;
    private string path;
    private long currentOffset;

    internal AccessDBContentReader(string path, AccessDBProvider provider)
    {
        this.path = path;
        this.provider = provider;
    }

    /// <summary>
    /// Read the specified number of rows from the source.
    /// </summary>
    /// <param name="readCount">The number of items to 
    /// return.</param>
    /// <returns>An array of elements read.</returns>
    public IList Read(long readCount)
    {
        // Read the number of rows specified by readCount and increment
        // offset
        string tableName;
        int rowNumber;
        PathType type = provider.GetNamesFromPath(path, out tableName, out rowNumber);

        Collection<DatabaseRowInfo> rows =
            provider.GetRows(tableName);
        Collection<DataRow> results = new Collection<DataRow>();

        if (currentOffset < 0 || currentOffset >= rows.Count)
        {
            return null;
        }

        int rowsRead = 0;

        while (rowsRead < readCount && currentOffset < rows.Count)
        {
            results.Add(rows[(int)currentOffset].Data);
            rowsRead++;
            currentOffset++;
        }

        return results;
    } // Read

    /// <summary>
    /// Moves the content reader specified number of rows from the 
    /// origin
    /// </summary>
    /// <param name="offset">Number of rows to offset</param>
    /// <param name="origin">Starting row from which to offset</param>
    public void Seek(long offset, System.IO.SeekOrigin origin)
    {
        // get the number of rows in the table which will help in
        // calculating current position
        string tableName;
        int rowNumber;

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

        if (type == PathType.Invalid)
        {
            throw new ArgumentException("Path specified must represent a table or a row :" + path);
        }

        if (type == PathType.Table)
        {
            Collection<DatabaseRowInfo> rows = provider.GetRows(tableName);

            int numRows = rows.Count;

            if (offset > rows.Count)
            {
                throw new
                       ArgumentException(
                           "Offset cannot be greater than the number of rows available"
                                        );
            }

            if (origin == System.IO.SeekOrigin.Begin)
            {
                // starting from Beginning with an index 0, the current offset
                // has to be advanced to offset - 1
                currentOffset = offset - 1;
            }
            else if (origin == System.IO.SeekOrigin.End)
            {
                // starting from the end which is numRows - 1, the current
                // offset is so much less than numRows - 1
                currentOffset = numRows - 1 - offset;
            }
            else
            {
                // calculate from the previous value of current offset
                // advancing forward always
                currentOffset += offset;
            }
        } // if (type...
        else
        {
            // for row, the offset will always be set to 0
            currentOffset = 0;
        }

    } // Seek

    /// <summary>
    /// Closes the content reader, so all members are reset
    /// </summary>
    public void Close()
    {
        Dispose();
    } // Close

    /// <summary>
    /// Dispose any resources being used
    /// </summary>
    public void Dispose()
    {
        Seek(0, System.IO.SeekOrigin.Begin);
        
        GC.SuppressFinalize(this);
    } // Dispose
} // AccessDBContentReader

Implementación de un redactor de contenido

Para escribir contenido en un elemento, un proveedor debe implementar una clase de redacción de contenido derivada de System.Management.Automation.Provider.Icontentwriter. La clase de redacción de contenido define un método Write que escribe el contenido de la fila especificada, un método Seek que mueve al escritor de contenido, un método Close que cierra el escritor de contenido y un método Dispose.

public class AccessDBContentWriter : IContentWriter
{
    // A provider instance is required so as to get "content"
    private AccessDBProvider provider;
    private string path;
    private long currentOffset;

    internal AccessDBContentWriter(string path, AccessDBProvider provider)
    {
        this.path = path;
        this.provider = provider;
    }

    /// <summary>
    /// Write the specified row contents in the source
    /// </summary>
    /// <param name="content"> The contents to be written to the source.
    /// </param>
    /// <returns>An array of elements which were successfully written to 
    /// the source</returns>
    /// 
    public IList Write(IList content)
    {
        if (content == null)
        {
            return null;
        }

        // Get the total number of rows currently available it will 
        // determine how much to overwrite and how much to append at
        // the end
        string tableName;
        int rowNumber;
        PathType type = provider.GetNamesFromPath(path, out tableName, out rowNumber);

        if (type == PathType.Table)
        {
            OdbcDataAdapter da = provider.GetAdapterForTable(tableName);
            if (da == null)
            {
                return null;
            }

            DataSet ds = provider.GetDataSetForTable(da, tableName);
            DataTable table = provider.GetDataTable(ds, tableName);

            string[] colValues = (content[0] as string).Split(',');

            // set the specified row
            DataRow row = table.NewRow();

            for (int i = 0; i < colValues.Length; i++)
            {
                if (!String.IsNullOrEmpty(colValues[i]))
                {
                    row[i] = colValues[i];
                }
            }

            //table.Rows.InsertAt(row, rowNumber);
            // Update the table
            table.Rows.Add(row);
            da.Update(ds, tableName);
            
        }
        else 
        {
            throw new InvalidOperationException("Operation not supported. Content can be added only for tables");
        }

        return null;
    } // Write

    /// <summary>
    /// Moves the content reader specified number of rows from the 
    /// origin
    /// </summary>
    /// <param name="offset">Number of rows to offset</param>
    /// <param name="origin">Starting row from which to offset</param>
    public void Seek(long offset, System.IO.SeekOrigin origin)
    {
        // get the number of rows in the table which will help in
        // calculating current position
        string tableName;
        int rowNumber;

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

        if (type == PathType.Invalid)
        {
            throw new ArgumentException("Path specified should represent either a table or a row : " + path);
        }

        Collection<DatabaseRowInfo> rows =
               provider.GetRows(tableName);

        int numRows = rows.Count;

        if (offset > rows.Count)
        {
            throw new
                   ArgumentException(
                       "Offset cannot be greater than the number of rows available"
                                           );
        }

        if (origin == System.IO.SeekOrigin.Begin)
        {
            // starting from Beginning with an index 0, the current offset
            // has to be advanced to offset - 1
            currentOffset = offset - 1;
        }
        else if (origin == System.IO.SeekOrigin.End)
        {
            // starting from the end which is numRows - 1, the current
            // offset is so much less than numRows - 1
            currentOffset = numRows - 1 - offset;
        }
        else
        {
            // calculate from the previous value of current offset
            // advancing forward always
            currentOffset += offset;
        }

    } // Seek

    /// <summary>
    /// Closes the content reader, so all members are reset
    /// </summary>
    public void Close()
    {
        Dispose();
    } // Close

    /// <summary>
    /// Dispose any resources being used
    /// </summary>
    public void Dispose()
    {
        Seek(0, System.IO.SeekOrigin.Begin);

        GC.SuppressFinalize(this);
    } // Dispose
} // AccessDBContentWriter

Recuperar el lector de contenido

Para obtener contenido de un elemento, el proveedor debe implementar System.Management.Automation.Provider.Icontentcmdletprovider.Getcontentreader* para admitir el cmdlet Get-Content. Este método devuelve el lector de contenido para el elemento ubicado en la ruta especificada. Luego se puede abrir el objeto lector para leer el contenido.

Aquí está la implementación de System.Management.Automation.Provider.Icontentcmdletprovider.Getcontentreader* para este método para este proveedor.

public IContentReader GetContentReader(string path)
{
    string tableName;
    int rowNumber;

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

    if (type == PathType.Invalid)
    {
        ThrowTerminatingInvalidPathException(path);
    }
    else if (type == PathType.Row)
    {
        throw new InvalidOperationException("contents can be obtained only for tables");
    }

    return new AccessDBContentReader(path, this);
} // GetContentReader
public IContentReader GetContentReader(string path)
{
    string tableName;
    int rowNumber;

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

    if (type == PathType.Invalid)
    {
        ThrowTerminatingInvalidPathException(path);
    }
    else if (type == PathType.Row)
    {
        throw new InvalidOperationException("contents can be obtained only for tables");
    }

    return new AccessDBContentReader(path, this);
} // GetContentReader

Cosas para recordar sobre la implementación de GetContentReader

Las siguientes condiciones pueden aplicarse a una implementación de System.Management.Automation.Provider.Icontentcmdletprovider.Getcontentreader*:

  • Al definir la clase de proveedor, un proveedor de contenido de Windows PowerShell puede declarar capacidades de proveedor de ExpandWildcards, Filter, Include o Exclude, de la enumeración System.Management.Automation.Provider.Providercapabilities. En estos casos, la implementación del método System.Management.Automation.Provider.Icontentcmdletprovider.Getcontentreader* debe garantizar que la ruta pasada al método cumpla con los requisitos de las capacidades especificadas. Para ello, el método debe acceder a la propiedad adecuada, por ejemplo, las propiedades System.Management.Automation.Provider.Cmdletprovider.Exclude* y System.Management.Automation.Provider.Cmdletprovider.Include*.

  • De forma predeterminada, las anulaciones de este método no deberían recuperar un lector de objetos que están ocultos para el usuario a menos que la propiedad System.Management.Automation.Provider.Cmdletprovider.Force* esté establecida en true. Se debe escribir un error si la ruta representa un elemento que está oculto para el usuario y System.Management.Automation.Provider.Cmdletprovider.Force* está establecido en false.

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

El cmdlet Get-Content puede requerir parámetros adicionales que se especifican dinámicamente en tiempo de ejecución. Para proporcionar estos parámetros dinámicos, el proveedor de contenido de Windows PowerShell debe implementar el método System.Management.Automation.Provider.Icontentcmdletprovider.Getcontentreaderdynamicparameters*. 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 similares a una clase de cmdlet o un objeto System.Management.Automation.Runtimedefinedparameterdictionary. El tiempo de ejecución de Windows PowerShell usa el objeto devuelto para agregar los parámetros al cmdlet.

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

public object GetContentReaderDynamicParameters(string path)
{
    return null;
}
public object GetContentReaderDynamicParameters(string path)
{
    return null;
}

Recuperar el escritor de contenido

Para escribir contenido en un elemento, el proveedor debe implementar System.Management.Automation.Provider.Icontentcmdletprovider.Getcontentwriter* para admitir los cmdlets Set-Content y Add-Content. Este método devuelve el escritor de contenido para el elemento ubicado en la ruta especificada.

Aquí está la implementación de System.Management.Automation.Provider.Icontentcmdletprovider.Getcontentwriter* para este método.

public IContentWriter GetContentWriter(string path)
{
    string tableName;
    int rowNumber;

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

    if (type == PathType.Invalid)
    {
        ThrowTerminatingInvalidPathException(path);
    }
    else if (type == PathType.Row)
    {
        throw new InvalidOperationException("contents can be added only to tables");
    }

    return new AccessDBContentWriter(path, this);
}
public IContentWriter GetContentWriter(string path)
{
    string tableName;
    int rowNumber;

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

    if (type == PathType.Invalid)
    {
        ThrowTerminatingInvalidPathException(path);
    }
    else if (type == PathType.Row)
    {
        throw new InvalidOperationException("contents can be added only to tables");
    }

    return new AccessDBContentWriter(path, this);
}

Cosas para recordar sobre la implementación de GetContentWriter

Las siguientes condiciones pueden aplicarse a su implementación de System.Management.Automation.Provider.Icontentcmdletprovider.Getcontentwriter*:

  • Al definir la clase de proveedor, un proveedor de contenido de Windows PowerShell puede declarar capacidades de proveedor de ExpandWildcards, Filter, Include o Exclude, de la enumeración System.Management.Automation.Provider.Providercapabilities. En estos casos, la implementación del método System.Management.Automation.Provider.Icontentcmdletprovider.Getcontentwriter* debe garantizar que la ruta pasada al método cumpla con los requisitos de las capacidades especificadas. Para ello, el método debe acceder a la propiedad adecuada, por ejemplo, las propiedades System.Management.Automation.Provider.Cmdletprovider.Exclude* y System.Management.Automation.Provider.Cmdletprovider.Include*.

  • De forma predeterminada, las anulaciones de este método no deberían recuperar un escritor para objetos que están ocultos para el usuario a menos que la propiedad System.Management.Automation.Provider.Cmdletprovider.Force* esté establecida en true. Se debe escribir un error si la ruta representa un elemento que está oculto para el usuario y System.Management.Automation.Provider.Cmdletprovider.Force* está establecido en false.

Adjuntar parámetros dinámicos a los cmdlets Agregar contenido y Establecer contenido

Los cmdlets Add-Content y Set-Content pueden requerir parámetros dinámicos adicionales que se agregan en tiempo de ejecución. Para proporcionar estos parámetros dinámicos, el proveedor de contenido de Windows PowerShell debe implementar el método System.Management.Automation.Provider.Icontentcmdletprovider.Getcontentwriterdynamicparameters* para controlar estos parámetros. 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 similares a una clase de cmdlet o un objeto System.Management.Automation.Runtimedefinedparameterdictionary. El tiempo de ejecución de Windows PowerShell usa el objeto devuelto para agregar los parámetros a los cmdlets.

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

public object GetContentWriterDynamicParameters(string path)
{
    return null;
}

Borrar contenido

Su proveedor de contenido implementa el método System.Management.Automation.Provider.Icontentcmdletprovider.Clearcontent* para admitir el cmdlet Clear-Content. Este método elimina el contenido del elemento en la ruta especificada, pero deja el elemento intacto.

A continuación se muestra la implementación del método System.Management.Automation.Provider.Icontentcmdletprovider.Clearcontent* para este proveedor.

public void ClearContent(string path)
{
    string tableName;
    int rowNumber;

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

    if (type != PathType.Table)
    {
        WriteError(new ErrorRecord(
            new InvalidOperationException("Operation not supported. Content can be cleared only for table"),
                "NotValidRow", ErrorCategory.InvalidArgument,
                    path));
        return;
    }

    OdbcDataAdapter da = GetAdapterForTable(tableName);

    if (da == null)
    {
        return;
    }

    DataSet ds = GetDataSetForTable(da, tableName);
    DataTable table = GetDataTable(ds, tableName);

    // Clear contents at the specified location
    for (int i = 0; i < table.Rows.Count; i++)
    {
        table.Rows[i].Delete();
    }

    if (ShouldProcess(path, "ClearContent"))
    {
        da.Update(ds, tableName);
    }

} // ClearContent

Cosas para recordar sobre la implementación de ClearContent

Las siguientes condiciones pueden aplicarse a una implementación de System.Management.Automation.Provider.Icontentcmdletprovider.Clearcontent*:

  • Al definir la clase de proveedor, un proveedor de contenido de Windows PowerShell puede declarar capacidades de proveedor de ExpandWildcards, Filter, Include o Exclude, de la enumeración System.Management.Automation.Provider.Providercapabilities. En estos casos, la implementación del método System.Management.Automation.Provider.Icontentcmdletprovider.Clearcontent* debe garantizar que la ruta pasada al método cumpla con los requisitos de las capacidades especificadas. Para ello, el método debe acceder a la propiedad adecuada, por ejemplo, las propiedades System.Management.Automation.Provider.Cmdletprovider.Exclude* y System.Management.Automation.Provider.Cmdletprovider.Include*.

  • De forma predeterminada, las anulaciones de este método no deberían borrar el contenido de los objetos que están ocultos para el usuario a menos que la propiedad System.Management.Automation.Provider.Cmdletprovider.Force* esté establecida en true. Se debe escribir un error si la ruta representa un elemento que está oculto para el usuario y System.Management.Automation.Provider.Cmdletprovider.Force* está establecido en false.

  • La implementación del método System.Management.Automation.Provider.Icontentcmdletprovider.Clearcontent* debe llamar a System.Management.Automation.Provider.Cmdletprovider.ShouldProcess y verificar su valor de retorno antes de realizar cambios en el almacén de datos. Este método se utiliza para confirmar la ejecución de una operación cuando se realiza un cambio en el almacén de datos, como borrar contenido. El método System.Management.Automation.Provider.Cmdletprovider.ShouldProcess envía el nombre del recurso que se va a cambiar al usuario, y el tiempo de ejecución de Windows PowerShell maneja cualquier configuración de línea de comandos o variables de preferencia para determinar qué se debe mostrar.

    Después de que la llamada a System.Management.Automation.Provider.Cmdletprovider.ShouldProcess devuelva true, el método System.Management.Automation.Provider.Icontentcmdletprovider.Clearcontent* debe llamar al método System.Management.Automation.Provider. Método cmdletprovider.ShouldContinue. Este método envía un mensaje al usuario para permitir comentarios para verificar si la operación debe continuar. La llamada a System.Management.Automation.Provider.Cmdletprovider.ShouldContinue permite una verificación adicional de modificaciones del sistema potencialmente peligrosas.

Adjuntar parámetros dinámicos al cmdlet Clear-Content

El cmdlet Clear-Content puede requerir parámetros dinámicos adicionales que se agregan en tiempo de ejecución. Para proporcionar estos parámetros dinámicos, el proveedor de contenido de Windows PowerShell debe implementar el método System.Management.Automation.Provider.Icontentcmdletprovider.Clearcontentdynamicparameters* para controlar estos parámetros. Este método recupera los parámetros del elemento en la ruta indicada. 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 similares a una clase de cmdlet o un objeto System.Management.Automation.Runtimedefinedparameterdictionary. El tiempo de ejecución de Windows PowerShell usa el objeto devuelto para agregar los parámetros al cmdlet.

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

public object ClearContentDynamicParameters(string path)
{
    return null;
}
public object ClearContentDynamicParameters(string path)
{
    return null;
}

Ejemplo de código

Para obtener un código de muestra completo, consulte Ejemplo de código de AccessDbProviderSample06.

Definición de tipos de objetos y formato

Al escribir un proveedor, puede ser necesario agregar miembros a objetos existentes o definir objetos nuevos. Una vez hecho esto, debe crear un archivo de tipos que Windows PowerShell pueda usar para identificar los miembros del objeto y un archivo de formato que defina cómo se muestra el objeto. Para obtener más información, consulte Ampliación de tipos de objetos y formato.

Creación del proveedor de Windows PowerShell

Consulte Cómo registrar cmdlets, proveedores y aplicaciones host.

Prueba del proveedor de Windows PowerShell

Cuando su proveedor de Windows PowerShell se haya registrado con Windows PowerShell, puede probarlo ejecutando los cmdlets compatibles en la línea de comandos. Por ejemplo, pruebe el proveedor de contenido de muestra.

Utilice el cmdlet Get-Content para recuperar el contenido del elemento especificado en la tabla de la base de datos en la ruta especificada por el parámetro Path. El parámetro ReadCount especifica el número de elementos que debe leer el lector de contenido definido (predeterminado 1). Con la siguiente entrada de comando, el cmdlet recupera dos filas (elementos) de la tabla y muestra su contenido. Tenga en cuenta que el siguiente ejemplo de salida utiliza una base de datos de Access ficticia.

Get-Content -Path mydb:\Customers -ReadCount 2
ID        : 1
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
ID        : 2
FirstName : Eva
LastName  : Corets
Email     : evacorets@cohowinery.com
Title     : Sales Representative
Company   : Coho Winery
WorkPhone : (360) 555-0100
Address   : 8910 Main Street
City      : Cabmerlot
State     : WA
Zip       : 98089
Country   : USA

Ver también

Crear proveedores de Windows PowerShell

Diseñe su proveedor de Windows PowerShell

Ampliación de tipos de objetos y formato

Implementar un proveedor de navegación Windows PowerShell

Cómo registrar cmdlets, proveedores y aplicaciones host

SDK de Windows PowerShell

Guía del programador de Windows PowerShell

Artículos relacionados