Delen via


Een Windows PowerShell Container Provider aanmaken

Dit onderwerp beschrijft hoe je een Windows PowerShell-provider kunt maken die kan werken op meerlagige datastores. Voor dit type datawinkel bevat het bovenste niveau van de opslag de root-items en wordt elk volgend niveau aangeduid als een knoop van kinditems. Door de gebruiker toe te staan op deze kindknooppunten te werken, kan een gebruiker hiërarchisch interacteren via de datastore.

Providers die kunnen werken aan multi-level datastores worden Windows PowerShell container providers genoemd. Wees je er echter van bewust dat een Windows PowerShell-containerprovider alleen gebruikt kan worden als er één container is (geen geneste containers) met items erin. Als er geneste containers zijn, moet je een Windows PowerShell-navigatieprovider implementeren. Voor meer informatie over het implementeren van een Windows PowerShell navigatieprovider, zie Het creëren van een Windows PowerShell navigatieprovider.

Opmerking

Je kunt het C#-bronbestand (AccessDBSampleProvider04.cs) van deze provider downloaden met behulp van de Microsoft Windows Software Development Kit voor Windows Vista en .NET Framework 3.0 Runtime Components. Voor downloadinstructies, zie Hoe installeer je Windows PowerShell en download de Windows PowerShell SDK. De gedownloade bronbestanden zijn beschikbaar in de <PowerShell Samples-map> . Voor meer informatie over andere implementaties van Windows PowerShell-providers, zie Designing Your Windows PowerShell Provider.

De hier beschreven Windows PowerShell-containerprovider definieert de database als zijn enkele container, waarbij de tabellen en rijen van de database worden gedefinieerd als items van de container.

Waarschuwing

Wees je ervan bewust dat dit ontwerp uitgaat van een database met een veld met de naam-ID, en dat het type veld LongInteger is.

Een Windows PowerShell Container Provider Class definiëren

Een Windows PowerShell-containerprovider moet een .NET-klasse definiëren die is afgeleid van de System.Management.Automation.Provider.ContainerCmdletProvider-basisklasse . Hier is de klassedefinitie voor de Windows PowerShell-containerprovider die in deze sectie wordt beschreven.

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

Let op dat in deze klassedefinitie het attribuut System.Management.Automation.Provider.CmdletProviderAttribute twee parameters bevat. De eerste parameter specificeert een gebruiksvriendelijke naam voor de provider die door Windows PowerShell wordt gebruikt. De tweede parameter specificeert de Windows PowerShell-specifieke mogelijkheden die de provider tijdens de commandoverwerking aan de Windows PowerShell-runtime blootstelt. Voor deze provider zijn er geen Windows PowerShell-specifieke mogelijkheden toegevoegd.

Basisfunctionaliteit definiëren

Zoals beschreven in Designing Your Windows PowerShell Provider, is de klasse System.Management.Automation.Provider.ContainerCmdletProvider afgeleid van verschillende andere klassen die verschillende providerfunctionaliteit boden. Een Windows PowerShell-containerprovider moet daarom alle functionaliteit definiëren die door die klassen wordt geleverd.

Om functionaliteit te implementeren voor het toevoegen van sessie-specifieke initialisatie-informatie en het vrijgeven van resources die door de provider worden gebruikt, zie Creating a Basic Windows PowerShell Provider. De meeste providers (inclusief de hier beschreven provider) kunnen echter de standaardimplementatie van deze functionaliteit gebruiken die door Windows PowerShell wordt geleverd.

Om toegang te krijgen tot de datastore, moet de provider de methoden van de System.Management.Automation.Provider.DriveDriveCmdletProvider-basisklasse implementeren. Voor meer informatie over het implementeren van deze methoden, zie Het aanmaken van een Windows PowerShell Drive Provider.

Om de items van een datawinkel te manipuleren, zoals het ophalen, instellen en wissen van items, moet de provider de methoden implementeren die worden geleverd door de System.Management.Automation.Provider.ItemCmdletProvider-basisklasse . Voor meer informatie over het implementeren van deze methoden, zie Het aanmaken van een Windows PowerShell Item Provider.

Kinditems ophalen

Om een kinditem op te halen, moet de Windows PowerShell-containerprovider de methode System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* overschrijven om aanroepen van de Get-ChildItem cmdlet te ondersteunen. Deze methode haalt kinditems uit de datastore op en schrijft ze als objecten naar de pijplijn. Als de recurse parameter van de cmdlet wordt gespecificeerd, haalt de methode alle kinderen op, ongeacht het niveau waarop ze zich bevinden. Als de recurse parameter niet is gespecificeerd, haalt de methode slechts één niveau van kinderen op.

Hier is de implementatie van de System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* methode voor deze provider. Let op dat deze methode de kinditems in alle databasetabellen ophaalt wanneer het pad de Access-database aangeeft, en de kinditems uit de rijen van die tabel ophaalt als het pad een datatabel aangeeft.

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

Dingen om te onthouden bij het implementeren van GetChildItems

De volgende voorwaarden kunnen van toepassing zijn op uw implementatie van System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems*:

Dynamische parameters toevoegen aan de Get-ChildItem cmdlet

Soms vereist de Get-ChildItem cmdlet die System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* aanroept extra parameters die dynamisch worden gespecificeerd tijdens runtime. Om deze dynamische parameters te bieden, moet de Windows PowerShell-containerprovider de System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItemsDynamicParameters* implementeren. Deze methode haalt dynamische parameters op voor het item op het aangegeven pad en geeft een object terug dat eigenschappen en velden heeft met parsingattributen vergelijkbaar met een cmdlet-klasse of een System.Management.Automation.RuntimeDefinedParameterDictionary-object . De Windows PowerShell-runtime gebruikt het geretourneerde object om de parameters aan de Get-ChildItem cmdlet toe te voegen.

Deze Windows PowerShell-containerprovider implementeert deze methode niet. De volgende code is echter de standaardimplementatie van deze methode.

Kind-itemnamen ophalen

Om de namen van kinditems op te halen, moet de Windows PowerShell-containerprovider de methode System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNames* overschrijven om aanroepen van de Get-ChildItem cmdlet te ondersteunen wanneer de parameter wordt Name opgegeven. Deze methode haalt de namen van de kinditems op voor het opgegeven pad of kinditemnamen voor alle containers als de returnAllContainers parameter van de cmdlet is opgegeven. Een kindnaam is het bladgedeelte van een pad. Bijvoorbeeld, de kindnaam van het pad C:\windows\system32\abc.dll is "abc.dll". De kindnaam van de map C:\windows\system32 is "system32".

Hier is de implementatie van de System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNames* methode voor deze provider. Let op dat de methode tabelnamen ophaalt als het opgegeven pad de Access-database (schijf) aangeeft en rijnummers als het pad een tabel aangeeft.

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

Dingen om te onthouden bij het implementeren van GetChildNames

De volgende voorwaarden kunnen van toepassing zijn op uw implementatie van System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems*:

Dynamische parameters toevoegen aan de Get-ChildItem cmdlet (naam)

Soms vereist de Get-ChildItem cmdlet (met de Name parameter) extra parameters die dynamisch worden gespecificeerd tijdens runtime. Om deze dynamische parameters te bieden, moet de Windows PowerShell-containerprovider de System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNamesDynamicParameters* implementeren. Deze methode haalt de dynamische parameters op voor het item op het aangegeven pad en geeft een object terug dat eigenschappen en velden heeft met parsingattributen vergelijkbaar met een cmdlet-klasse of een System.Management.Automation.RuntimeDefinedParameterDictionary-object . De Windows PowerShell-runtime gebruikt het geretourneerde object om de parameters aan de Get-ChildItem cmdlet toe te voegen.

Deze aanbieder voert deze methode niet toe. De volgende code is echter de standaardimplementatie van deze methode.

Items hernoemen

Om een item te hernoemen, moet een Windows PowerShell-containerprovider de methode System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem* overschrijven om aanroepen van de Rename-Item cmdlet te ondersteunen. Deze methode verandert de naam van het item op het opgegeven pad naar de nieuwe naam. De nieuwe naam moet altijd relatief zijn tot het ouderitem (container).

Deze provider overschrijft de System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem*- methode niet. Het volgende is echter de standaardimplementatie.

Dingen om te onthouden bij het implementeren van RenameItem

De volgende voorwaarden kunnen van toepassing zijn op uw implementatie van System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem*:

Dynamische parameters toevoegen aan de Rename-Item cmdlet

Soms vereist de Rename-Item cmdlet extra parameters die dynamisch worden gespecificeerd tijdens runtime. Om deze dynamische parameters te bieden, moet de Windows PowerShell container provider de System.Management.Automation.Provider.ContainerCmdletProvider.RenameItemDynamicParameters* methode implementeren. Deze methode haalt de parameters voor het item op op het aangegeven pad en geeft een object terug dat eigenschappen en velden heeft met parsingattributen vergelijkbaar met een cmdlet-klasse of een System.Management.Automation.RuntimeDefinedParameterDictionary-object . De Windows PowerShell-runtime gebruikt het geretourneerde object om de parameters aan de Rename-Item cmdlet toe te voegen.

Deze containerprovider implementeert deze methode niet. De volgende code is echter de standaardimplementatie van deze methode.

Nieuwe items creëren

Om nieuwe items te maken, moet een containerprovider de methode System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* implementeren om aanroepen van de New-Item cmdlet te ondersteunen. Deze methode creëert een data-item dat zich bevindt op het opgegeven pad. De type parameter van de cmdlet bevat het door de provider gedefinieerde type voor het nieuwe item. De FileSystem-provider gebruikt bijvoorbeeld een type parameter met de waarde "file" of "directory". De newItemValue parameter van de cmdlet specificeert een provider-specifieke waarde voor het nieuwe item.

Hier is de implementatie van de System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* methode voor deze provider.

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

Dingen om te onthouden bij het implementeren van NewItem

De volgende voorwaarden kunnen van toepassing zijn op uw implementatie van System.Management.Automation.Provider.ContainerCmdletProvider.NewItem*:

Dynamische parameters toevoegen aan de New-Item cmdlet

Soms vereist de New-Item cmdlet extra parameters die dynamisch worden gespecificeerd tijdens runtime. Om deze dynamische parameters te bieden, moet de containerprovider de System.Management.Automation.Provider.ContainerCmdletProvider.NewItemDynamicParameters* methode implementeren. Deze methode haalt de parameters voor het item op op het aangegeven pad en geeft een object terug dat eigenschappen en velden heeft met parsingattributen vergelijkbaar met een cmdlet-klasse of een System.Management.Automation.RuntimeDefinedParameterDictionary-object . De Windows PowerShell-runtime gebruikt het geretourneerde object om de parameters aan de New-Item cmdlet toe te voegen.

Deze aanbieder voert deze methode niet toe. De volgende code is echter de standaardimplementatie van deze methode.

Items verwijderen

Om items te verwijderen, moet de Windows PowerShell-provider de methode System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItem* overschrijven om aanroepen van de Remove-Item cmdlet te ondersteunen. Deze methode verwijdert een item uit de datastore op het opgegeven pad. Als de recurse parameter van de Remove-Item cmdlet is ingesteld op true, verwijdert de methode alle kinditems ongeacht hun niveau. Als de parameter op is gezet false, verwijdert de methode slechts één item op het opgegeven pad.

Deze aanbieder ondersteunt geen verwijdering van voorwerpen. De volgende code is echter de standaardimplementatie van System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItem*.

Dingen om te onthouden bij het implementeren van RemoveItem

De volgende voorwaarden kunnen van toepassing zijn op uw implementatie van System.Management.Automation.Provider.ContainerCmdletProvider.NewItem*:

Dynamische parameters toevoegen aan de Remove-Item cmdlet

Soms vereist de Remove-Item cmdlet extra parameters die dynamisch worden gespecificeerd tijdens runtime. Om deze dynamische parameters te bieden, moet de containerprovider de methode System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItemDynamicParameters* implementeren om deze parameters te verwerken. Deze methode haalt de dynamische parameters op voor het item op het aangegeven pad en geeft een object terug dat eigenschappen en velden heeft met parsingattributen vergelijkbaar met een cmdlet-klasse of een System.Management.Automation.RuntimeDefinedParameterDictionary-object . De Windows PowerShell-runtime gebruikt het geretourneerde object om de parameters aan de Remove-Item cmdlet toe te voegen.

Deze containerprovider implementeert deze methode niet. De volgende code is echter de standaardimplementatie van System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItemDynamicParameters*.

Zoekopdrachten voor kinditems

Om te controleren of er kinditems bestaan op het opgegeven pad, moet de Windows PowerShell-containerprovider de methode System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems* overschrijven. Deze methode geeft terug true als het item kinderen heeft, en false anders. Voor een nul- of leeg pad beschouwt de methode alle items in de datawinkel als kinderen en geeft trueterug .

Hier is de override-versie voor de System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems* -methode. Als er meer dan twee paddelen zijn gemaakt door de ChunkPath-hulpmethode, geeft de methode , falseaangezien alleen een databasecontainer en een tabelcontainer zijn gedefinieerd. Voor meer informatie over deze helpermethode, zie de ChunkPath-methode die wordt besproken in Het creëren van een Windows PowerShell Item Provider.

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

return results;

Dingen om te onthouden bij het implementeren van HasChildItems

De volgende voorwaarden kunnen van toepassing zijn op uw implementatie van System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems*:

Kopiëren van items

Om items te kopiëren, moet de containerprovider de methode System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem implementeren om aanroepen van de Copy-Item cmdlet te ondersteunen. Deze methode kopieert een data-item van de locatie aangegeven door de path parameter van de cmdlet naar de locatie die door de copyPath parameter wordt aangegeven. Als de recurse parameter is gespecificeerd, kopieert de methode alle subcontainers. Als de parameter niet is gespecificeerd, kopieert de methode slechts één niveau van items.

Deze aanbieder voert deze methode niet toe. De volgende code is echter de standaardimplementatie van System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem.

Dingen om te onthouden bij het implementeren van CopyItem

De volgende voorwaarden kunnen van toepassing zijn op uw implementatie van System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem:

Dynamische parameters toevoegen aan de Copy-Item cmdlet

Soms vereist de Copy-Item cmdlet extra parameters die dynamisch worden gespecificeerd tijdens runtime. Om deze dynamische parameters te bieden, moet de Windows PowerShell-containerprovider de methode System.Management.Automation.Provider.ContainerCmdletProvider.CopyItemDynamicParameters* implementeren om deze parameters te verwerken. Deze methode haalt de parameters voor het item op op het aangegeven pad en geeft een object terug dat eigenschappen en velden heeft met parsingattributen vergelijkbaar met een cmdlet-klasse of een System.Management.Automation.RuntimeDefinedParameterDictionary-object . De Windows PowerShell-runtime gebruikt het geretourneerde object om de parameters aan de Copy-Item cmdlet toe te voegen.

Deze aanbieder voert deze methode niet toe. De volgende code is echter de standaardimplementatie van System.Management.Automation.Provider.ContainerCmdletProvider.CopyItemDynamicParameters*.

Codevoorbeeld

Voor volledige voorbeeldcode, zie AccessDbProviderSample04 Code Voorbeeld.

De Windows PowerShell Provider bouwen

Bekijk hoe u cmdlets, providers en hostapplicaties registreert.

Het testen van de Windows PowerShell Provider

Wanneer je Windows PowerShell-provider geregistreerd is bij Windows PowerShell, kun je dit testen door de ondersteunde cmdlets op de commandoregel uit te voeren. Let op dat de volgende voorbeeldoutput een fictieve Access-database gebruikt.

  1. Voer de Get-ChildItem cmdlet uit om de lijst met kinditems op te halen uit een Customers-tabel in de Access-database.

    Get-ChildItem mydb:customers
    

    De volgende output verschijnt.

    PSPath        : AccessDB::customers
    PSDrive       : mydb
    PSProvider    : System.Management.Automation.ProviderInfo
    PSIsContainer : True
    Data          : System.Data.DataRow
    Name          : Customers
    RowCount      : 91
    Columns       :
    
  2. Voer de Get-ChildItem cmdlet opnieuw uit om de data van een tabel op te halen.

    (Get-ChildItem mydb:customers).Data
    

    De volgende output verschijnt.

    TABLE_CAT   : C:\PS\northwind
    TABLE_SCHEM :
    TABLE_NAME  : Customers
    TABLE_TYPE  : TABLE
    REMARKS     :
    
  3. Gebruik nu de Get-Item cmdlet om de items op rij 0 in de datatabel op te halen.

    Get-Item mydb:\customers\0
    

    De volgende output verschijnt.

    PSPath        : AccessDB::customers\0
    PSDrive       : mydb
    PSProvider    : System.Management.Automation.ProviderInfo
    PSIsContainer : False
    Data          : System.Data.DataRow
    RowNumber     : 0
    
  4. Hergebruik Get-Item om de gegevens van de items in rij 0 op te halen.

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

    De volgende output verschijnt.

    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. Gebruik nu de New-Item cmdlet om een rij toe te voegen aan een bestaande tabel. De Path parameter specificeert het volledige pad naar de rij en moet een rijnummer aangeven dat groter is dan het bestaande aantal rijen in de tabel. De Type parameter geeft aan Row dat je welk type item moet toevoegen. Ten slotte specificeert de Value parameter een komma-gescheiden lijst van kolomwaarden voor de rij.

    New-Item -Path mydb:\Customers\3 -ItemType "Row" -Value "3,CustomerFirstName,CustomerLastName,CustomerEmailAddress,CustomerTitle,CustomerCompany,CustomerPhone, CustomerAddress,CustomerCity,CustomerState,CustomerZip,CustomerCountry"
    
  6. Controleer de correctheid van de nieuwe itembewerking als volgt.

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

    De volgende output verschijnt.

    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
    

Zie ook

Windows PowerShell-providers aanmaken

Ontwerpen van je Windows PowerShell-provider

Implementatie van een item Windows PowerShell-provider

Implementatie van een Navigatie Windows PowerShell-provider

Hoe registreer je cmdlets, providers en hostapplicaties

Windows PowerShell SDK

Windows PowerShell Programmeursgids