Skapa en Windows PowerShell-containerprovider

Det här avsnittet beskriver hur du skapar en Windows PowerShell-provider som kan arbeta med datalager med flera lager. För den här typen av datalager innehåller den översta nivån i arkivet rotobjekten och varje efterföljande nivå kallas en nod för underordnade objekt. Genom att tillåta användaren att arbeta med dessa underordnade noder kan en användare interagera hierarkiskt via datalagret.

Leverantörer som kan arbeta med datalager på flera nivåer kallas för Windows PowerShell containerproviders. Tänk dock på att en Windows PowerShell containerprovider endast kan användas när det finns en container (inga kapslade containrar) med objekt i den. Om det finns kapslade containrar måste du implementera en Windows PowerShell navigeringsprovider. Mer information om hur du implementerar Windows PowerShell navigeringsprovider finns i Skapa en Windows PowerShell-navigeringsprovider.

Anteckning

Du kan ladda ned C#-källfilen (AccessDBSampleProvider04.cs) för den här providern med hjälp av Microsoft Windows Software Development Kit för Windows Vista- och .NET Framework 3.0 Runtime-komponenter. Anvisningar för nedladdning finns i Installera Windows PowerShell och Ladda ned Windows PowerShell SDK. De nedladdade källfilerna är tillgängliga i <PowerShell Samples> katalogen . Mer information om andra Windows PowerShell-providerimplementering finns i Designing Your Windows PowerShell Provider (Utforma Windows PowerShell provider).

Den Windows PowerShell containerprovider som beskrivs här definierar databasen som dess enda container, där tabellerna och raderna i databasen definieras som objekt i containern.

Varning

Tänk på att den här designen förutsätter en databas som har ett fält med namnet ID och att fältets typ är LongInteger.

Definiera en Windows PowerShell-containerproviderklass

En Windows PowerShell måste definiera en .NET-klass som härleds från basklassen System.Management.Automation.Provider.Containercmdletprovider. Här är klassdefinitionen för den Windows PowerShell som beskrivs i det här avsnittet.

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

Observera att attributet System.Management.Automation.Provider.Cmdletproviderattribute innehåller två parametrar i den här klassdefinitionen. Den första parametern anger ett användarvänligt namn för providern som används av Windows PowerShell. Den andra parametern anger Windows PowerShell specifika funktioner som providern exponerar för Windows PowerShell under kommandobearbetningen. För den här providern finns det Windows PowerShell specifika funktioner som läggs till.

Definiera grundläggande funktioner

Enligt beskrivningen i Designing Your Windows PowerShell Provider(Utforma din Windows PowerShell provider) härleds klassen System.Management.Automation.Provider.Containercmdletprovider från flera andra klasser som tillhandahöll olika providerfunktioner. En Windows PowerShell containerprovider måste därför definiera alla funktioner som tillhandahålls av dessa klasser.

Information om hur du implementerar funktioner för att lägga till sessionsspecifik initieringsinformation och frigöra resurser som används av providern finns i Skapa en grundläggande Windows PowerShell provider. De flesta leverantörer (inklusive providern som beskrivs här) kan dock använda standardimplementering av den här funktionen som tillhandahålls av Windows PowerShell.

För att få åtkomst till datalagret måste providern implementera metoderna för basklassen System.Management.Automation.Provider.Drivecmdletprovider. Mer information om hur du implementerar dessa metoder finns i Creating an Windows PowerShell Drive Provider.

Om du vill ändra objekten i ett datalager, till exempel hämta, ange och rensa objekt, måste providern implementera de metoder som tillhandahålls av basklassen System.Management.Automation.Provider.Itemcmdletprovider. Mer information om hur du implementerar dessa metoder finns i Creating an Windows PowerShell Item Provider.

Hämta underordnade objekt

Om du vill hämta ett underobjekt måste Windows PowerShell-containerprovidern åsidosätta metoden System.Management.Automation.Provider.Containercmdletprovider.Getchilditems* för att stödja anrop från Get-ChildItem cmdleten . Den här metoden hämtar underordnade objekt från datalagret och skriver dem till pipelinen som objekt. Om parametern för cmdleten anges hämtar metoden alla underordnade data oavsett vilken recurse nivå de finns på. Om recurse parametern inte anges hämtar metoden bara en enda nivå med underordnade.

Här är implementeringen av metoden System.Management.Automation.Provider.Containercmdletprovider.Getchilditems* för den här providern. Observera att den här metoden hämtar underordnade objekt i alla databastabeller när sökvägen anger Access-databasen och hämtar de underordnade objekten från raderna i tabellen om sökvägen anger en datatabell.

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

Saker att komma ihåg om att implementera GetChildItems

Följande villkor kan gälla för din implementering av System.Management.Automation.Provider.Containercmdletprovider.Getchilditems*:

Koppla dynamiska parametrar till Get-ChildItem cmdlet

Ibland kräver Get-ChildItem cmdleten som anropar System.Management.Automation.Provider.Containercmdletprovider.Getchilditems* ytterligare parametrar som anges dynamiskt vid körning. För att tillhandahålla dessa dynamiska parametrar måste Windows PowerShell-containerprovidern implementera metoden System.Management.Automation.Provider.Containercmdletprovider.Getchilditemsdynamicparameters*. Den här metoden hämtar dynamiska parametrar för objektet på den angivna sökvägen och returnerar ett objekt som har egenskaper och fält med parsningsattribut som liknar en cmdlet-klass eller ett System.Management.Automation.Runtimedefinedparameterdictionary-objekt. Den Windows PowerShell runtime använder det returnerade objektet för att lägga till parametrarna i Get-ChildItem cmdleten.

Den Windows PowerShell containerprovidern implementerar inte den här metoden. Följande kod är dock standardimplementering av den här metoden.

Hämta underordnade objektnamn

Om du vill hämta namnen på underordnade objekt måste Windows PowerShell-containerprovidern åsidosätta metoden System.Management.Automation.Provider.Containercmdletprovider.Getchildnames* för att stödja anrop från Get-ChildItem cmdleten när Name dess parameter anges. Den här metoden hämtar namnen på de underordnade objekten för den angivna sökvägen eller underordnade objektnamn för alla containrar om returnAllContainers parametern för cmdleten har angetts. Ett undernamn är lövdelen av en sökväg. Till exempel är det underordnade namnet för sökvägen c:\windows\system32\abc.dll "abc.dll". Det underordnade namnet för katalogen c:\windows\system32 är "system32".

Här är implementeringen av metoden System.Management.Automation.Provider.Containercmdletprovider.Getchildnames* för den här providern. Observera att metoden hämtar tabellnamn om den angivna sökvägen anger Access-databasen (enheten) och radnumren om sökvägen anger en tabell.

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

Saker att komma ihåg om att implementera GetChildNames

Följande villkor kan gälla för din implementering av System.Management.Automation.Provider.Containercmdletprovider.Getchilditems*:

Koppla dynamiska parametrar till Get-ChildItem cmdlet (namn)

Ibland kräver Get-ChildItem cmdleten Name (med parametern) ytterligare parametrar som anges dynamiskt vid körning. För att tillhandahålla dessa dynamiska parametrar måste Windows PowerShell-containerprovidern implementera metoden System.Management.Automation.Provider.Containercmdletprovider.Getchildnamesdynamicparameters*. Den här metoden hämtar de dynamiska parametrarna för objektet på den angivna sökvägen och returnerar ett objekt som har egenskaper och fält med parsningsattribut som liknar en cmdlet-klass eller ett System.Management.Automation.Runtimedefinedparameterdictionary-objekt. Den Windows PowerShell runtime använder det returnerade objektet för att lägga till parametrarna i Get-ChildItem cmdleten.

Den här providern implementerar inte den här metoden. Följande kod är dock standardimplementering av den här metoden.

Byta namn på objekt

Om du vill byta namn på ett objekt måste en Windows PowerShell-containerprovider åsidosätta metoden System.Management.Automation.Provider.Containercmdletprovider.Renameitem* för att stödja anrop från Rename-Item cmdleten . Den här metoden ändrar namnet på objektet på den angivna sökvägen till det nya angivna namnet. Det nya namnet måste alltid vara relativt det överordnade objektet (containern).

Den här providern åsidosätter inte metoden System.Management.Automation.Provider.Containercmdletprovider.Renameitem*. Följande är dock standardimplementering.

Saker att komma ihåg om att implementera RenameItem

Följande villkor kan gälla för din implementering av System.Management.Automation.Provider.Containercmdletprovider.Renameitem*:

Koppla dynamiska parametrar till Rename-Item cmdlet

Ibland kräver Rename-Item cmdleten ytterligare parametrar som anges dynamiskt vid körning. Om du vill ange dessa dynamiska parametrar Windows PowerShell en containerprovider implementera metoden System.Management.Automation.Provider.Containercmdletprovider.Renameitemdynamicparameters*. Den här metoden hämtar parametrarna för objektet på den angivna sökvägen och returnerar ett objekt som har egenskaper och fält med parsningsattribut som liknar en cmdlet-klass eller ett System.Management.Automation.Runtimedefinedparameterdictionary-objekt. Den Windows PowerShell körningen använder det returnerade objektet för att lägga till parametrarna i Rename-Item cmdleten.

Den här containerprovidern implementerar inte den här metoden. Följande kod är dock standardimplementering av den här metoden.

Skapa nya objekt

Om du vill skapa nya objekt måste en containerprovider implementera metoden System.Management.Automation.Provider.Containercmdletprovider.Newitem* för att stödja anrop från New-Item cmdleten . Den här metoden skapar ett dataobjekt som finns på den angivna sökvägen. Parametern type för cmdleten innehåller den providerdefinierade typen för det nya objektet. FileSystem-providern använder till exempel en type parameter med värdet "file" eller "directory". Parametern newItemValue för cmdleten anger ett providerspecifikt värde för det nya objektet.

Här är implementeringen av metoden System.Management.Automation.Provider.Containercmdletprovider.Newitem* för den här providern.

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

Saker att komma ihåg om att implementera NewItem

Följande villkor kan gälla för din implementering av System.Management.Automation.Provider.Containercmdletprovider.Newitem*:

Koppla dynamiska parametrar till New-Item cmdlet

Ibland kräver New-Item cmdleten ytterligare parametrar som anges dynamiskt vid körning. Om du vill ange dessa dynamiska parametrar måste containerprovidern implementera metoden System.Management.Automation.Provider.Containercmdletprovider.Newitemdynamicparameters*. Den här metoden hämtar parametrarna för objektet på den angivna sökvägen och returnerar ett objekt som har egenskaper och fält med parsningsattribut som liknar en cmdlet-klass eller ett System.Management.Automation.Runtimedefinedparameterdictionary-objekt. Den Windows PowerShell körningen använder det returnerade objektet för att lägga till parametrarna i New-Item cmdleten.

Den här providern implementerar inte den här metoden. Följande kod är dock standardimplementering av den här metoden.

Ta bort objekt

Om du vill ta bort objekt måste Windows PowerShell-providern åsidosätta metoden System.Management.Automation.Provider.Containercmdletprovider.Removeitem* för att stödja anrop från Remove-Item cmdleten. Den här metoden tar bort ett objekt från datalagret på den angivna sökvägen. Om recurse parametern för Remove-Item cmdleten är inställd på true tar metoden bort alla underordnade objekt oavsett nivå. Om parametern är inställd på false tar metoden bara bort ett enskilt objekt på den angivna sökvägen.

Den här providern stöder inte borttagning av objekt. Följande kod är dock standardimplementering av System.Management.Automation.Provider.Containercmdletprovider.Removeitem*.

Saker att komma ihåg om att implementera RemoveItem

Följande villkor kan gälla för din implementering av System.Management.Automation.Provider.Containercmdletprovider.Newitem*:

Koppla dynamiska parametrar till Remove-Item cmdlet

Ibland kräver Remove-Item cmdleten ytterligare parametrar som anges dynamiskt vid körning. Om du vill ange dessa dynamiska parametrar måste containerprovidern implementera metoden System.Management.Automation.Provider.Containercmdletprovider.Removeitemdynamicparameters* för att hantera dessa parametrar. Den här metoden hämtar de dynamiska parametrarna för objektet på den angivna sökvägen och returnerar ett objekt som har egenskaper och fält med parsningsattribut som liknar en cmdlet-klass eller ett System.Management.Automation.Runtimedefinedparameterdictionary-objekt. Den Windows PowerShell körningen använder det returnerade objektet för att lägga till parametrarna i Remove-Item cmdleten.

Den här containerprovidern implementerar inte den här metoden. Följande kod är dock standardimplementering av System.Management.Automation.Provider.Containercmdletprovider.Removeitemdynamicparameters*.

Fråga efter underordnade objekt

Om du vill kontrollera om det finns underordnade objekt på den angivna sökvägen måste Windows PowerShell-containerprovidern åsidosätta metoden System.Management.Automation.Provider.Containercmdletprovider.Haschilditems*. Den här metoden true returnerar om objektet har underordnade objekt och false annars. För en null- eller tom sökväg betraktar metoden alla objekt i datalagret som underordnade och returnerar true .

Här är åsidosättningen för metoden System.Management.Automation.Provider.Containercmdletprovider.Haschilditems*. Om det finns fler än två sökvägsdelar som skapats av hjälpmetoden ChunkPath returnerar metoden , eftersom endast en databascontainer och false en tabellcontainer har definierats. Mer information om den här hjälpmetoden finns i ChunkPath-metoden beskrivs i Skapa en Windows PowerShell objektprovider.

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

return results;

Saker att komma ihåg om att implementera HasChildItems

Följande villkor kan gälla för din implementering av System.Management.Automation.Provider.Containercmdletprovider.Haschilditems*:

Kopiera objekt

För att kunna kopiera objekt måste containerprovidern implementera metoden System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem för att stödja anrop från Copy-Item cmdleten . Den här metoden kopierar ett dataobjekt från den plats som anges av parametern för cmdleten till den path plats som anges av copyPath parametern . Om recurse parametern anges kopierar metoden alla undercontainrar. Om parametern inte anges kopierar metoden endast en enda nivå med objekt.

Den här providern implementerar inte den här metoden. Följande kod är dock standardimplementering av System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem.

Saker att komma ihåg om att implementera CopyItem

Följande villkor kan gälla för din implementering av System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem:

Koppla dynamiska parametrar till Copy-Item cmdlet

Ibland kräver Copy-Item cmdleten ytterligare parametrar som anges dynamiskt vid körning. För att tillhandahålla dessa dynamiska parametrar måste Windows PowerShell-containerprovidern implementera metoden System.Management.Automation.Provider.Containercmdletprovider.Copyitemdynamicparameters* för att hantera dessa parametrar. Den här metoden hämtar parametrarna för objektet på den angivna sökvägen och returnerar ett objekt som har egenskaper och fält med parsningsattribut som liknar en cmdlet-klass eller ett System.Management.Automation.Runtimedefinedparameterdictionary-objekt. Den Windows PowerShell körningen använder det returnerade objektet för att lägga till parametrarna i Copy-Item cmdleten.

Den här providern implementerar inte den här metoden. Följande kod är dock standardimplementering av System.Management.Automation.Provider.Containercmdletprovider.Copyitemdynamicparameters*.

Kodexempel

Fullständig exempelkod finns i AccessDbProviderSample04 Code Sample.

Skapa Windows PowerShell providern

Se Registrera cmdlets, providers och värdprogram.

Testa Windows PowerShell providern

När din Windows PowerShell har registrerats med Windows PowerShell kan du testa den genom att köra de cmdlets som stöds på kommandoraden. Tänk på att följande exempelutdata använder en fiktiv Access-databas.

  1. Kör Get-ChildItem cmdleten för att hämta listan över underordnade objekt från tabellen Customers i Access-databasen.

    Get-ChildItem mydb:customers
    

    Följande utdata visas.

    PSPath        : AccessDB::customers
    PSDrive       : mydb
    PSProvider    : System.Management.Automation.ProviderInfo
    PSIsContainer : True
    Data          : System.Data.DataRow
    Name          : Customers
    RowCount      : 91
    Columns       :
    
  2. Kör Get-ChildItem cmdleten igen för att hämta data för en tabell.

    (Get-ChildItem mydb:customers).data
    

    Följande utdata visas.

    TABLE_CAT   : c:\PS\northwind
    TABLE_SCHEM :
    TABLE_NAME  : Customers
    TABLE_TYPE  : TABLE
    REMARKS     :
    
  3. Använd nu Get-Item cmdleten för att hämta objekten på rad 0 i datatabellen.

    Get-Item mydb:\customers\0
    

    Följande utdata visas.

    PSPath        : AccessDB::customers\0
    PSDrive       : mydb
    PSProvider    : System.Management.Automation.ProviderInfo
    PSIsContainer : False
    Data          : System.Data.DataRow
    RowNumber     : 0
    
  4. Återanvänd Get-Item för att hämta data för objekten på rad 0.

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

    Följande utdata visas.

    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. Använd nu New-Item cmdleten för att lägga till en rad i en befintlig tabell. Parametern anger den fullständiga sökvägen till raden och måste ange ett radnummer som är större än det Path befintliga antalet rader i tabellen. Parametern Type anger "rad" för att ange den typ av objekt som ska läggas till. Slutligen anger Value parametern en kommaavgränsad lista med kolumnvärden för raden.

    New-Item -Path mydb:\Customers\3 -ItemType "row" -Value "3,CustomerFirstName,CustomerLastName,CustomerEmailAddress,CustomerTitle,CustomerCompany,CustomerPhone, CustomerAddress,CustomerCity,CustomerState,CustomerZip,CustomerCountry"
    
  6. Kontrollera att åtgärden för det nya objektet är korrekt på följande sätt.

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

    Följande utdata visas.

    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
    

Se även

Skapa Windows PowerShell providers

Designa en Windows PowerShell-provider

Implementera en Windows PowerShell provider

Implementera en Windows PowerShell navigeringsprovider

Registrera cmdlets, providers och värdprogram

Windows PowerShell SDK

Programmeringsguide för Windows PowerShell