Condividi tramite


Creare un provider di container PowerShell per Windows

Questo argomento descrive come creare un provider PowerShell per Windows che possa lavorare su archivi dati multilivello. Per questo tipo di archivio dati, il livello superiore dello store contiene gli elementi radici e ogni livello successivo è chiamato nodo di elementi figli. Permettendo all'utente di lavorare su questi nodi figli, può interagire gerarchicamente attraverso lo store dati.

I fornitori che possono lavorare su archivi dati multilivello sono chiamati provider di container Windows PowerShell. Tuttavia, tieni presente che un provider di container PowerShell per Windows può essere utilizzato solo quando c'è un container (nessun container annidato) con elementi al suo interno. Se ci sono container annidati, allora devi implementare un provider di navigazione Windows PowerShell. Per maggiori informazioni sull'implementazione del provider di navigazione Windows PowerShell, vedi Creare un provider di navigazione Windows PowerShell.

Annotazioni

Puoi scaricare il file sorgente C# (AccessDBSampleProvider04.cs) di questo fornitore utilizzando il Microsoft Windows Software Development Kit per Windows Vista e i componenti runtime di .NET Framework 3.0. Per le istruzioni per il download, consulta Come installare Windows PowerShell e scaricare l'SDK di Windows PowerShell. I file sorgente scaricati sono disponibili nella <directory PowerShell Samples> . Per maggiori informazioni su altre implementazioni di provider PowerShell di Windows, vedi Progettare il tuo provider PowerShell Windows.

Il provider di container PowerShell per Windows descritto qui definisce il database come il suo unico contenitore, con le tabelle e le righe del database definite come elementi del container.

Attenzione

Tieni presente che questo design presuppone un database che ha un campo con il nome ID, e che il tipo del campo sia LongInteger.

Definizione di una classe di provider container PowerShell di Windows

Un provider container Windows PowerShell deve definire una classe .NET che derivi dalla classe base System.Management.Automation.Provider.ContainerCmdletProvider . Ecco la definizione di classe per il provider di container Windows PowerShell descritto in questa sezione.

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

Si noti che in questa definizione di classe, l'attributo System.Management.Automation.Provider.CmdletProviderAttribute include due parametri. Il primo parametro specifica un nome user-friendly per il provider utilizzato da Windows PowerShell. Il secondo parametro specifica le capacità specifiche di Windows PowerShell che il provider espone all'runtime di Windows PowerShell durante l'elaborazione dei comandi. Per questo fornitore, non sono state aggiunte funzionalità specifiche di Windows PowerShell.

Definizione della funzionalità di base

Come descritto in Designing Your Windows PowerShell Provider, la classe System.Management.Automation.Provider.ContainerCmdletProvider deriva da diverse altre classi che offrivano funzionalità diverse per i fornitori. Un provider di container PowerShell di Windows, quindi, deve definire tutte le funzionalità fornite da queste classi.

Per implementare funzionalità per aggiungere informazioni di inizializzazione specifiche per sessione e per rilasciare risorse utilizzate dal provider, vedi Creare un provider base di PowerShell per Windows. Tuttavia, la maggior parte dei provider (incluso quello descritto qui) può utilizzare l'implementazione predefinita di questa funzionalità fornita da Windows PowerShell.

Per accedere allo store dati, il provider deve implementare i metodi della classe base System.Management.Automation.Provider.DriveCmdletProvider . Per maggiori informazioni sull'implementazione di questi metodi, vedi Creare un provider di unità PowerShell per Windows.

Per manipolare gli elementi di un archivio dati, come ottenere, impostare e cancellare gli elementi, il provider deve implementare i metodi forniti dalla classe base System.Management.Automation.Provider.ItemCmdletProvider . Per maggiori informazioni sull'implementazione di questi metodi, vedi Creare un fornitore di oggetti PowerShell per Windows.

Recupero degli oggetti per bambini

Per recuperare un elemento figlio, il provider del container PowerShell di Windows deve sovrascrivere il metodo System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* per supportare le chiamate dal Get-ChildItem cmdlet. Questo metodo recupera gli elementi figli dal data store e li scrive nella pipeline come oggetti. Se il recurse parametro del cmdlet viene specificato, il metodo recupera tutti i figli indipendentemente dal livello a cui si trovano. Se il recurse parametro non è specificato, il metodo recupera solo un singolo livello di figli.

Ecco l'implementazione del metodo System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* per questo fornitore. Si noti che questo metodo recupera gli elementi figli in tutte le tabelle del database quando il percorso indica il database Access, e recupera gli elementi figli dalle righe di quella tabella se il percorso indica una tabella dati.

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

Cose da ricordare sull'implementazione di GetChildItems

Le seguenti condizioni possono applicarsi alla tua implementazione di System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems*:

Attacco dei parametri dinamici al Get-ChildItem cmdlet

A volte il Get-ChildItem cmdlet che chiama System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* richiede parametri aggiuntivi specificati dinamicamente a runtime. Per fornire questi parametri dinamici, il provider di container PowerShell di Windows deve implementare il metodo System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItemsDynamicParameters* . Questo metodo recupera parametri dinamici per l'elemento sul percorso indicato e restituisce un oggetto che possiede proprietà e campi con attributi di analisi simili a una classe cmdlet o a un oggetto System.Management.Automation.RuntimeDefinedParameterDictionary . L'runtime di Windows PowerShell utilizza l'oggetto restituito per aggiungere i parametri al Get-ChildItem cmdlet.

Questo provider di container Windows PowerShell non implementa questo metodo. Tuttavia, il seguente codice è l'implementazione predefinita di questo metodo.

Recupero dei nomi degli oggetti figli

Per recuperare i nomi degli elementi figli, il provider del container PowerShell di Windows deve sovrascrivere il metodo System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNames* per supportare le chiamate dal Get-ChildItem cmdlet quando il parametro Name è specificato. Questo metodo recupera i nomi degli elementi figli per il percorso specificato o i nomi degli elementi figli per tutti i contenitori se il returnAllContainers parametro del cmdlet è specificato. Un nome bambino è la parte fogliosa di un sentiero. Ad esempio, il nome figlio per il percorso C:\windows\system32\abc.dll è "abc.dll". Il nome figlio della directory C:\windows\system32 è "system32".

Ecco l'implementazione del metodo System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNames* per questo fornitore. Si noti che il metodo recupera i nomi delle tabelle se il percorso specificato indica il database Access (unità) e i numeri di riga se il percorso indica una tabella.

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

Cose da ricordare sull'implementazione di GetChildNames

Le seguenti condizioni possono applicarsi alla tua implementazione di System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems*:

Aggiunta dei parametri dinamici al Get-ChildItem cmdlet (nome)

A volte il Get-ChildItem cmdlet (con il parametro Name ) richiede parametri aggiuntivi specificati dinamicamente a runtime. Per fornire questi parametri dinamici, il fornitore di container PowerShell di Windows deve implementare il metodo System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNamesDynamicParameters* . Questo metodo recupera i parametri dinamici dell'elemento sul percorso indicato e restituisce un oggetto che possiede proprietà e campi con attributi di analisi simili a una classe cmdlet o a un oggetto System.Management.Automation.RuntimeDefinedParameterDictionary . L'runtime di Windows PowerShell utilizza l'oggetto restituito per aggiungere i parametri al Get-ChildItem cmdlet.

Questo fornitore non implementa questo metodo. Tuttavia, il seguente codice è l'implementazione predefinita di questo metodo.

Rinomina degli elementi

Per rinominare un elemento, un provider di container Windows PowerShell deve sovrascrivere il metodo System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem* per supportare le chiamate dal Rename-Item cmdlet. Questo metodo cambia il nome dell'oggetto nel percorso specificato con il nuovo nome fornito. Il nuovo nome deve sempre essere relativo all'elemento genitore (contenitore).

Questo provider non sovrascrive il metodo System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem* . Tuttavia, quanto segue è l'implementazione predefinita.

Cose da ricordare sull'implementazione di RenameItem

Le seguenti condizioni possono applicarsi alla tua implementazione di System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem*:

Attacco dei parametri dinamici al Rename-Item cmdlet

A volte il Rename-Item cmdlet richiede parametri aggiuntivi specificati dinamicamente a runtime. Per fornire questi parametri dinamici, il provider di container PowerShell di Windows deve implementare il metodo System.Management.Automation.Provider.ContainerCmdletProvider.RenameItemDynamicParameters* . Questo metodo recupera i parametri dell'elemento nel percorso indicato e restituisce un oggetto che possiede proprietà e campi con attributi di parsing simili a una classe cmdlet o a un oggetto System.Management.Automation.RuntimeDefinedParameterDictionary . L'runtime di Windows PowerShell utilizza l'oggetto restituito per aggiungere i parametri al Rename-Item cmdlet.

Questo fornitore di container non implementa questo metodo. Tuttavia, il seguente codice è l'implementazione predefinita di questo metodo.

Creazione di nuovi oggetti

Per creare nuovi elementi, un provider di container deve implementare il metodo System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* per supportare le chiamate dal New-Item cmdlet. Questo metodo crea un elemento dati situato sul percorso specificato. Il type parametro del cmdlet contiene il tipo definito dal fornitore per il nuovo elemento. Ad esempio, il provider del FileSystem utilizza un type parametro con valore di "file" o "directory". Il parametro newItemValue del cmdlet specifica un valore specifico per il provider del nuovo elemento.

Ecco l'implementazione del metodo System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* per questo fornitore.

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];

Cose da ricordare sull'implementazione di NewItem

Le seguenti condizioni possono applicarsi alla tua implementazione di System.Management.Automation.Provider.ContainerCmdletProvider.NewItem*:

Attacco dei parametri dinamici al New-Item cmdlet

A volte il New-Item cmdlet richiede parametri aggiuntivi specificati dinamicamente a runtime. Per fornire questi parametri dinamici, il fornitore del container deve implementare il metodo System.Management.Automation.Provider.ContainerCmdletProvider.NewItemDynamicParameters* . Questo metodo recupera i parametri dell'elemento nel percorso indicato e restituisce un oggetto che possiede proprietà e campi con attributi di parsing simili a una classe cmdlet o a un oggetto System.Management.Automation.RuntimeDefinedParameterDictionary . L'runtime di Windows PowerShell utilizza l'oggetto restituito per aggiungere i parametri al New-Item cmdlet.

Questo fornitore non implementa questo metodo. Tuttavia, il seguente codice è l'implementazione predefinita di questo metodo.

Rimozione degli oggetti

Per rimuovere elementi, il provider PowerShell di Windows deve sovrascrivere il metodo System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItem* per supportare le chiamate dal Remove-Item cmdlet. Questo metodo elimina un elemento dallo store dati sul percorso specificato. Se il parametro recurse del Remove-Item cmdlet è impostato su true, il metodo rimuove tutti gli elementi figli indipendentemente dal loro livello. Se il parametro è impostato a false, il metodo rimuove solo un singolo elemento nel percorso specificato.

Questo fornitore non supporta la rimozione degli oggetti. Tuttavia, il seguente codice è l'implementazione predefinita di System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItem*.

Cose da ricordare sull'implementazione di RemoveItem

Le seguenti condizioni possono applicarsi alla tua implementazione di System.Management.Automation.Provider.ContainerCmdletProvider.NewItem*:

Attacco dei parametri dinamici al Remove-Item cmdlet

A volte il Remove-Item cmdlet richiede parametri aggiuntivi specificati dinamicamente a runtime. Per fornire questi parametri dinamici, il fornitore del container deve implementare il metodo System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItemDynamicParameters* per gestirli. Questo metodo recupera i parametri dinamici dell'elemento sul percorso indicato e restituisce un oggetto che possiede proprietà e campi con attributi di analisi simili a una classe cmdlet o a un oggetto System.Management.Automation.RuntimeDefinedParameterDictionary . L'runtime di Windows PowerShell utilizza l'oggetto restituito per aggiungere i parametri al Remove-Item cmdlet.

Questo fornitore di container non implementa questo metodo. Tuttavia, il seguente codice è l'implementazione predefinita di System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItemDynamicParameters*.

Interrogazione per gli elementi figli

Per verificare se gli elementi figli esistono sul percorso specificato, il provider del container PowerShell di Windows deve sovrascrivere il metodo System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems* . Questo metodo ritorna true se l'articolo ha figli, e false altrimenti. Per un percorso nullo o vuoto, il metodo considera qualsiasi elemento nello store dati come figli e restituisce true.

Ecco l'override per il metodo System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems* . Se il metodo ChunkPath helper crea più di due parti di percorso, il metodo restituisce false, poiché sono definiti solo un container del database e un container di tabella. Per maggiori informazioni su questo metodo helper, vedi il metodo ChunkPath discusso in Creating a Windows PowerShell Item Provider.

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

return results;

Cose da ricordare sull'implementazione di HasChildItems

Le seguenti condizioni possono applicarsi alla tua implementazione di System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems*:

Copia degli elementi

Per copiare gli elementi, il provider del container deve implementare il metodo System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem per supportare le chiamate dal Copy-Item cmdlet. Questo metodo copia un elemento dati dalla posizione indicata dal path parametro del cmdlet alla posizione indicata dal parametro copyPath . Se il recurse parametro è specificato, il metodo copia tutti i sottocontenitori. Se il parametro non è specificato, il metodo copia solo un singolo livello di elementi.

Questo fornitore non implementa questo metodo. Tuttavia, il seguente codice è l'implementazione predefinita di System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem.

Cose da ricordare sull'implementazione di CopyItem

Le seguenti condizioni possono applicarsi alla tua implementazione di System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem:

Attacco dei parametri dinamici al Copy-Item cmdlet

A volte il Copy-Item cmdlet richiede parametri aggiuntivi specificati dinamicamente a runtime. Per fornire questi parametri dinamici, il provider di container PowerShell di Windows deve implementare il metodo System.Management.Automation.Provider.ContainerCmdletProvider.CopyItemDynamicParameters* per gestire questi parametri. Questo metodo recupera i parametri dell'elemento nel percorso indicato e restituisce un oggetto che possiede proprietà e campi con attributi di parsing simili a una classe cmdlet o a un oggetto System.Management.Automation.RuntimeDefinedParameterDictionary . L'runtime di Windows PowerShell utilizza l'oggetto restituito per aggiungere i parametri al Copy-Item cmdlet.

Questo fornitore non implementa questo metodo. Tuttavia, il seguente codice è l'implementazione predefinita di System.Management.Automation.Provider.ContainerCmdletProvider.CopyItemDynamicParameters*.

Codice di esempio

Per il codice di esempio completo, vedi AccessDbProviderSample04 Code Sample.

Costruire il provider PowerShell di Windows

Vedi come registrare cmdlet, fornitori e applicazioni host.

Test del provider PowerShell di Windows

Quando il tuo provider PowerShell di Windows è stato registrato con Windows PowerShell, puoi testarlo eseguendo i cmdlet supportati nella riga di comando. Tieni presente che il seguente esempio di output utilizza un database Access fittizio.

  1. Esegui il Get-ChildItem cmdlet per recuperare l'elenco degli elementi figli da una tabella Clienti nel database di Access.

    Get-ChildItem mydb:customers
    

    Compare il seguente risultato.

    PSPath        : AccessDB::customers
    PSDrive       : mydb
    PSProvider    : System.Management.Automation.ProviderInfo
    PSIsContainer : True
    Data          : System.Data.DataRow
    Name          : Customers
    RowCount      : 91
    Columns       :
    
  2. Esegui di nuovo il Get-ChildItem cmdlet per recuperare i dati di una tabella.

    (Get-ChildItem mydb:customers).Data
    

    Compare il seguente risultato.

    TABLE_CAT   : C:\PS\northwind
    TABLE_SCHEM :
    TABLE_NAME  : Customers
    TABLE_TYPE  : TABLE
    REMARKS     :
    
  3. Ora usa il Get-Item cmdlet per recuperare gli elementi alla riga 0 nella tabella dati.

    Get-Item mydb:\customers\0
    

    Compare il seguente risultato.

    PSPath        : AccessDB::customers\0
    PSDrive       : mydb
    PSProvider    : System.Management.Automation.ProviderInfo
    PSIsContainer : False
    Data          : System.Data.DataRow
    RowNumber     : 0
    
  4. Riutilizza Get-Item per recuperare i dati degli elementi nella riga 0.

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

    Compare il seguente risultato.

    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. Ora usa il New-Item cmdlet per aggiungere una riga a una tabella esistente. Il Path parametro specifica il percorso completo verso la riga e deve indicare un numero di righe maggiore rispetto al numero esistente di righe nella tabella. Il parametro Type indica Row di specificare il tipo di elemento da aggiungere. Infine, il parametro Value specifica una lista delimitata da virgole dei valori delle colonne per la riga.

    New-Item -Path mydb:\Customers\3 -ItemType "Row" -Value "3,CustomerFirstName,CustomerLastName,CustomerEmailAddress,CustomerTitle,CustomerCompany,CustomerPhone, CustomerAddress,CustomerCity,CustomerState,CustomerZip,CustomerCountry"
    
  6. Verifica la correttezza del nuovo funzionamento dell'articolo come segue.

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

    Compare il seguente risultato.

    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
    

Vedere anche

Creazione di provider PowerShell per Windows

Progettare il tuo provider PowerShell per Windows

Implementazione di un Provider Windows PowerShell Item

Implementazione di un provider PowerShell per la navigazione di Windows

Come registrare cmdlet, fornitori e applicazioni host

Windows PowerShell SDK

Guida per programmatori PowerShell di Windows