本主题描述如何创建一个能够在多层数据存储上运行的 Windows PowerShell 提供者。 对于这种类型的数据存储,存储的顶层包含根项,每个后续层级被称为子项的节点。 通过允许用户在这些子节点上工作,用户可以通过数据存储进行分层交互。
能够在多层数据存储上工作的提供者被称为Windows PowerShell容器提供者。 但请注意,Windows PowerShell 容器提供者只能在存在一个容器(无嵌套容器)且包含项目时使用。 如果存在嵌套容器,那么你必须实现一个 Windows PowerShell 导航提供者。 有关实现 Windows PowerShell 导航提供者的更多信息,请参见 创建 Windows PowerShell 导航提供者。
注释
您可以使用 Windows Vista 和 .NET Framework 3.0 运行时组件的 Microsoft Windows 软件开发工具包下载该提供者的 C# 源文件(AccessDBSampleProvider04.cs)。 有关下载说明,请参见 《如何安装Windows PowerShell》和《Windows PowerShell SDK》。 下载的源文件可在 <PowerShell Samples> 目录中获取。 有关其他 Windows PowerShell 提供者实现的更多信息,请参见 “设计你的 Windows PowerShell 提供者”。
这里描述的 Windows PowerShell 容器提供者将数据库定义为其单一容器,数据库的表和行定义为容器中的项。
注意
请注意,这种设计假设数据库有一个带有名称 ID 的字段,且字段类型为 LongInteger。
定义 Windows PowerShell 容器提供者类
Windows PowerShell 容器提供者必须定义一个从 System.Management.Automation.Provider.ContainerCmdletProvider 基类派生的 .NET 类。 以下是本节中描述的 Windows PowerShell 容器提供者的类定义。
[CmdletProvider("AccessDB", ProviderCapabilities.None)]
public class AccessDBProvider : ContainerCmdletProvider
注意,在该类定义中, System.Management.Automation.Provider.CmdletProviderAttribute 属性包含两个参数。 第一个参数指定了 Windows PowerShell 所用提供者的用户友好名称。 第二个参数指定了 Windows PowerShell 在命令处理过程中向 Windows PowerShell 运行时暴露的具体功能。 对于该提供者,没有添加任何 Windows PowerShell 特定的功能。
定义基础功能
如《 设计你的 Windows PowerShell 提供者》中所述, System.Management.Automation.Provider.ContainerCmdletProvider 类源自其他提供不同提供者功能的类。 因此,Windows PowerShell 容器提供者需要定义这些类提供的所有功能。
要实现添加会话特定初始化信息和释放提供者使用的资源的功能,请参见 创建基础 Windows PowerShell 提供者。 然而,大多数提供者(包括此处描述的提供者)可以使用 Windows PowerShell 提供的该功能的默认实现。
为了访问数据存储,提供者必须实现 System.Management.Automation.Provider.DriveCmdletProvider 基类的方法。 关于实现这些方法的更多信息,请参见 创建 Windows PowerShell 驱动器提供者。
为了作数据存储中的项目,如获取、设置和清除项目,提供者必须实现 System.Management.Automation.Provider.ItemCmdletProvider 基类提供的方法。 关于实现这些方法的更多信息,请参见 创建 Windows PowerShell 项提供者。
取回子物品
要检索子项,Windows PowerShell 容器提供者必须覆盖 System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* 方法,以支持该 Get-ChildItem 命令调用。 该方法从数据存储中检索子项,并将其写入流水线作为对象。 如果 recurse 指定了 cmdlet 的参数,方法会检索所有子节点,无论它们处于哪个层级。 如果未指定参数, recurse 方法只检索单个子节点层。
这是该提供者 System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* 方法的实现。 注意,当路径指示为Access数据库时,该方法检索所有数据库表中的子项;如果路径指示为数据表,则从该表的行中检索子项。
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
关于实现GetChildItems需要记住的事项
以下条件可能适用于您的 System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems*的实现:
在定义提供者类时,Windows PowerShell 容器提供者可能会声明 System.Management.Automation.Provider.ProviderCapabilities 枚举中的 ExpandWildcard、Filter、Include 或 Exclude 等提供者能力。 在这种情况下, System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* 方法的实现需要确保传递给该方法的路径满足指定能力的要求。 为此,方法应访问相应属性,例如 System.Management.Automation.Provider.CmdletProvider.Exclude* 和 System.Management.Automation.Provider.CmdletProvider.Include* 属性。
该方法的实现应考虑任何可能使物品对用户可见的访问方式。 例如,如果用户通过 FileSystem 提供者(由 Windows PowerShell 提供)对文件有写权限,但没有读取权限,文件仍然存在, System.Management.Automation.Provider.ItemCmdletProvider.ItemExists* 返回
true。 你的实现可能需要检查父项,看看子项是否可以枚举。在编写多个项目时, System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* 方法可能需要一些时间。 你可以用 System.Management.Automation.Provider.CmdletProvider.WriteItemObject* 方法,一个一个地写入这些项目。 使用这种方法后,这些物品会以流的形式呈现给用户。
你对 System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* 的实现负责防止循环链接等情况下的无限递归。 应抛出合适的终止异常以反映此类条件。
将动态参数附加到 Get-ChildItem cmdlet
有时调用System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems*的Get-ChildItemcmdlet需要在运行时动态指定额外参数。 为了提供这些动态参数,Windows PowerShell 容器提供者必须实现 System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItemsDynamicParameters* 方法。 该方法检索指定路径上的动态参数,返回一个具有类似 cmdlet 类或 System.Management.Automation.RuntimeDefinedParameterDictionary 对象的属性和字段的对象。 Windows PowerShell 运行时使用返回的对象将参数添加到 Get-ChildItem cmdlet。
该 Windows PowerShell 容器提供者未实现此方法。 不过,以下代码是该方法的默认实现。
检索子物品名称
为了获取子项的名称,Windows PowerShell 容器提供者必须覆盖 System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNames* 方法,以支持在参数指定时调用 Get-ChildItem 该命令 Name 。 该方法会检索指定路径的子项名称,或者如果 returnAllContainers cmdlet 参数指定了,则获取所有容器的子项名称。 子名称是路径的叶子部分。 例如,路径 C:\windows\system32\abc.dll 的子名称是“abc.dll”。 目录 C:\windows\system32 的子名称是“system32”。
这是该提供者 System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNames* 方法的实现。 注意,如果指定的路径指向 Access 数据库(驱动器),则检索表名;如果路径指示表,则检索行号。
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
关于实现GetChildNames需要注意的事项
以下条件可能适用于您的 System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems*的实现:
在定义提供者类时,Windows PowerShell 容器提供者可能会声明 System.Management.Automation.Provider.ProviderCapabilities 枚举中的 ExpandWildcard、Filter、Include 或 Exclude 等提供者能力。 在这种情况下, System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* 方法的实现需要确保传递给该方法的路径满足指定能力的要求。 为此,方法应访问相应属性,例如 System.Management.Automation.Provider.CmdletProvider.Exclude* 和 System.Management.Automation.Provider.CmdletProvider.Include* 属性。
注释
当
returnAllContainers指定了 cmdlet 的参数时,这一规则有例外。 在这种情况下,方法应当检索容器的任何子名称,即使该子名称与 System.Management.Automation.Provider.CmdletProvider.Filter*、 System.Management.Automation.Provider.CmdletProvider.Include*或 System.Management.Automation.Provider.CmdletProvider.Exclude* 属性的值不匹配。默认情况下,除非指定 了System.Management.Automation.Provider.CmdletProvider.Force* 属性,否则该方法的覆盖不应检索通常对用户隐藏的对象名称。 如果指定的路径指向容器,则不需要 System.Management.Automation.Provider.CmdletProvider.Force* 属性。
你对 System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNames* 的实现负责防止循环链接等情况下的无限递归。 应抛出合适的终止异常以反映此类条件。
将动态参数附加到 Get-ChildItem cmdlet(名称)
有时 Get-ChildItem cmdlet(带参数 Name )需要运行时动态指定额外参数。 为了提供这些动态参数,Windows PowerShell 容器提供者必须实现 System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNamesDynamicParameters* 方法。 该方法检索指定路径上项目的动态参数,返回一个具有类似于 cmdlet 类或 System.Management.Automation.RuntimeDefinedParameterDictionary 对象的属性和字段的对象。 Windows PowerShell 运行时使用返回的对象将参数添加到 Get-ChildItem cmdlet。
该提供者未实现该方法。 不过,以下代码是该方法的默认实现。
更名项目
要重命名一个项目,Windows PowerShell 容器提供者必须覆盖 System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem* 方法,以支持该 Rename-Item 命令的调用。 该方法将指定路径上的项目名称更改为新名称。 新名称必须始终相对于父项(容器)命名。
该提供者不会覆盖 System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem* 方法。 不过,以下是默认实现。
实现RenameItem需要注意的事项
以下条件可能适用于您的 System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem*的实现:
在定义提供者类时,Windows PowerShell 容器提供者可能会声明 System.Management.Automation.Provider.ProviderCapabilities 枚举中的 ExpandWildcard、Filter、Include 或 Exclude 等提供者能力。 在这种情况下, System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* 方法的实现需要确保传递给该方法的路径满足指定能力的要求。 为此,方法应访问相应属性,例如 System.Management.Automation.Provider.CmdletProvider.Exclude* 和 System.Management.Automation.Provider.CmdletProvider.Include* 属性。
System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem* 方法仅用于修改项目名称,不用于移动作。 如果
newName参数包含路径分隔符,或者可能导致项目改变父节点位置,你的方法实现应写错。默认情况下,除非指定 System.Management.Automation.Provider.CmdletProvider.Force* 属性,否则该方法的覆写不应重命名对象。 如果指定的路径指向容器,则不需要 System.Management.Automation.Provider.CmdletProvider.Force* 属性。
你实现的 System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem* 方法应调用 System.Management.Automation.Provider.CmdletProvider.ShouldProcess 并检查其返回值,然后再对数据存储做任何更改。 该方法用于确认作执行,当系统状态发生变化时,例如重命名文件。 System.Management.Automation.Provider.CmdletProvider.ShouldProcess 会将待更改资源的名称发送给用户,Windows PowerShell 运行时会考虑命令行设置或偏好变量来决定显示内容。
在调用 System.Management.Automation.Provider.CmdletProvider.ShouldProcess 返回
true后, System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem* 方法应调用 System.Management.Automation.Provider.CmdletProvider.ShouldContinue 方法。 该方法向用户发送确认消息,以便获得额外反馈,判断作是否应继续。 提供者应致电 System.Management.Automation.Provider.CmdletProvider.WithContinue ,以进一步检查潜在危险的系统修改。
将动态参数附加到 Rename-Item cmdlet
有时 Rename-Item cmdlet 需要在运行时动态指定额外参数。 为了提供这些动态参数,Windows PowerShell 容器提供者必须实现 System.Management.Automation.Provider.ContainerCmdletProvider.RenameItemDynamicParameters* 方法。 该方法检索指定路径上的参数,返回一个具有属性和场的对象,解析属性类似于 cmdlet 类或 System.Management.Automation.RuntimeDefinedParameterDictionary 对象。 Windows PowerShell 运行时使用返回的对象将参数添加到 Rename-Item cmdlet。
该容器提供者未实现该方法。 不过,以下代码是该方法的默认实现。
创建新物品
要创建新项,容器提供者必须实现 System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* 方法以支持该 New-Item 命令调用。 该方法会生成位于指定路径的数据项。
type cmdlet 的参数包含新项目的提供者定义类型。 例如,文件系统提供者使用 type 一个参数,取值为“file”或“directory”。
newItemValue cmdlet 的参数指定了新项目的提供者特定值。
这是该提供者系统管理自动化服务提供者. ContainerCmdletProvider.NewItem* 方法的实现。
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];
关于实施NewItem需要记住的事项
以下条件可能适用于您对 System.Management.Automation.Provider.ContainerCmdletProvider.NewItem*的实现:
System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* 方法应对参数中传递
type的字符串进行大小写不区分的比较。 这也应该能让比赛变得最不模糊。 例如,对于“file”和“directory”这两个类型,只需第一个字母即可消歧。 如果参数type指示提供者无法创建的类型, System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* 方法应写入 ArgumentException,并提示提供者可创建的类型。对于
newItemValue参数,建议实现 System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* 方法,至少接受字符串。 它还应接受 System.Management.Automation.Provider.ItemCmdletProvider.GetItem* 方法检索到的同一路径的对象类型。 System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* 方法可以使用 System.Management.Automation.LanguagePrimitives.ConvertTo* 方法将类型转换为所需类型。你实现 System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* 方法时,应调用 System.Management.Automation.Provider.CmdletProvider.ShouldProcess 并检查其返回值,然后再对数据存储做任何更改。 在调用 System.Management.Automation.Provider.CmdletProvider.ShouldProcess 返回为真后, System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* 方法应调用 System.Management.Automation.Provider.CmdletProvider.ShouldContinue 方法,作为潜在危险系统修改的额外检查。
将动态参数附加到 New-Item cmdlet
有时 New-Item cmdlet 需要在运行时动态指定额外参数。 为了提供这些动态参数,容器提供者必须实现 System.Management.Automation.Provider.ContainerCmdletProvider.NewItemDynamicParameters* 方法。 该方法检索指定路径上的参数,返回一个具有属性和场的对象,解析属性类似于 cmdlet 类或 System.Management.Automation.RuntimeDefinedParameterDictionary 对象。 Windows PowerShell 运行时使用返回的对象将参数添加到 New-Item cmdlet。
该提供者未实现该方法。 不过,以下代码是该方法的默认实现。
移除物品
要移除项目,Windows PowerShell 提供者必须覆盖 System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItem* 方法,以支持从 cmdlet 调用 Remove-Item 。 该方法在指定路径处从数据存储中删除一个项目。 如果 recurseRemove-Item cmdlet 参数设置为 true,方法会删除所有子项,无论其级别如何。 如果参数设置为 false,方法只在指定路径上移除一个项目。
该服务商不支持物品移除。 然而,以下代码是 System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItem*的默认实现。
关于实现RemoveItem需要记住的事项
以下条件可能适用于您对 System.Management.Automation.Provider.ContainerCmdletProvider.NewItem*的实现:
在定义提供者类时,Windows PowerShell 容器提供者可能会声明 System.Management.Automation.Provider.ProviderCapabilities 枚举中的 ExpandWildcard、Filter、Include 或 Exclude 等提供者能力。 在这种情况下, System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* 方法的实现需要确保传递给该方法的路径满足指定能力的要求。 为此,方法应访问相应属性,例如 System.Management.Automation.Provider.CmdletProvider.Exclude* 和 System.Management.Automation.Provider.CmdletProvider.Include* 属性。
默认情况下,除非将 System.Management.Automation.Provider.CmdletProvider.Force* 属性设置为 true,否则该方法的覆写不应移除对象。 如果指定的路径指向容器,则不需要 System.Management.Automation.Provider.CmdletProvider.Force* 属性。
你对 System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItem* 的实现负责防止循环链接等情况下的无限递归。 应抛出合适的终止异常以反映此类条件。
你实现 System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItem* 方法时,应调用 System.Management.Automation.Provider.CmdletProvider.ShouldProcess 并检查其返回值,然后再对数据存储进行任何更改。 在调用 System.Management.Automation.Provider.CmdletProvider.ShouldProcess 返回
true后, System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItem* 方法应调用 System.Management.Automation.Provider.CmdletProvider.ShouldContinue 方法,作为潜在危险系统修改的额外检查。
将动态参数附加到 Remove-Item cmdlet
有时 Remove-Item cmdlet 需要在运行时动态指定额外参数。 为了提供这些动态参数,容器提供者必须实现 System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItemDynamicParameters* 方法来处理这些参数。 该方法检索指定路径上项目的动态参数,返回一个具有类似于 cmdlet 类或 System.Management.Automation.RuntimeDefinedParameterDictionary 对象的属性和字段的对象。 Windows PowerShell 运行时使用返回的对象将参数添加到 Remove-Item cmdlet。
该容器提供者未实现该方法。 然而,以下代码是 System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItemDynamicParameters*的默认实现。
查询子项
为了检查指定路径是否存在子项,Windows PowerShell 容器提供者必须覆盖 System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems* 方法。 如果该项有子项,则返回该方法,false否则返回true。 对于空路径或空路径,方法将数据存储中的任意项视为子节点,返回 true。
这是 System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems* 方法的覆盖。 如果 ChunkPath 辅助方法 false创建的路径部分超过两个,方法返回 ,因为只定义了一个数据库容器和一个表容器。 关于该辅助方法的更多信息,请参见 ChunkPath 方法,该方法在 《创建 Windows PowerShell 项提供者》中已有讨论。
protected override bool HasChildItems( string path )
{
return false;
} // HasChildItems
ErrorCategory.InvalidOperation, tableName));
}
return results;
关于实现 HasChildItems 需要注意的事项
以下条件可能适用于您对 System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems*的实现:
- 如果容器提供者暴露了一个包含有趣挂载点的根节点, System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems* 方法的实现应当路径传递空字符串或空字符串时返回
true。
复制物品
要复制项目,容器提供者必须实现 System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem 方法以支持该 Copy-Item 命令调用。 该方法将数据项从指令小子参数指示 path 的位置复制到参数指示 copyPath 的位置。 如果 recurse 参数被指定,方法会复制所有子容器。 如果参数未指定,方法只复制一层项。
该提供者未实现该方法。 然而,以下代码是 System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem的默认实现。
实现CopyItem需要记住的事项
以下条件可能适用于您对 System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem的实现:
在定义提供者类时,Windows PowerShell 容器提供者可能会声明 System.Management.Automation.Provider.ProviderCapabilities 枚举中的 ExpandWildcard、Filter、Include 或 Exclude 等提供者能力。 在这种情况下, System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* 方法的实现需要确保传递给该方法的路径满足指定能力的要求。 为此,方法应访问相应属性,例如 System.Management.Automation.Provider.CmdletProvider.Exclude* 和 System.Management.Automation.Provider.CmdletProvider.Include* 属性。
默认情况下,除非将 System.Management.Automation.Provider.CmdletProvider.Force* 属性设置为
true。 例如,FileSystem提供者不会在已有 C:\abc.txt 文件上复制 C:\temp\abc.txt,除非 System.Management.Automation.Provider.CmdletProvider.Force* 属性设置为true。 如果参数中指定的copyPath路径存在且指向容器,则不需要 System.Management.Automation.Provider.CmdletProvider.Force* 属性。 在这种情况下, System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem 应将参数指示path的项目复制到该参数指定的copyPath容器,作为子节点。你对 System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem 的实现负责防止循环链接等无穷递归。 应抛出合适的终止异常以反映此类条件。
System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem方法的实现应在对数据存储进行任何更改前,调用System.Management.Automation.Provider.CmdletProvider.ShouldProcess并检查其返回值。 在调用 System.Management.Automation.Provider.CmdletProvider.ShouldProcess 返回为true后, System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem 方法应调用 System.Management.Automation.Provider.CmdletProvider.ShouldContinue 方法,作为对潜在危险系统修改的额外检查。 有关调用这些方法的更多信息,请参见 “重命名项”。
将动态参数附加到 Copy-Item cmdlet
有时 Copy-Item cmdlet 需要在运行时动态指定额外参数。 为了提供这些动态参数,Windows PowerShell 容器提供者必须实现 System.Management.Automation.Provider.ContainerCmdletProvider.CopyItemDynamicParameters* 方法来处理这些参数。 该方法检索指定路径上的参数,返回一个具有属性和场的对象,解析属性类似于 cmdlet 类或 System.Management.Automation.RuntimeDefinedParameterDictionary 对象。 Windows PowerShell 运行时使用返回的对象将参数添加到 Copy-Item cmdlet。
该提供者未实现该方法。 然而,以下代码是 System.Management.Automation.Provider.ContainerCmdletProvider.CopyItemDynamicParameters*的默认实现。
代码示例
完整的示例代码,请参见 AccessDbProviderSample04 代码示例。
构建 Windows PowerShell 提供者
请参阅 如何注册指令、提供者和托管应用程序。
测试Windows PowerShell提供者
当你的 Windows PowerShell 提供者已注册 Windows PowerShell 后,可以通过命令行运行支持的 cmdlet 来测试。 请注意,以下示例输出使用了一个虚构的Access数据库。
运行
Get-ChildItemcmdlet 从 Access 数据库中的客户表中获取子项列表。Get-ChildItem mydb:customers以下是输出内容。
PSPath : AccessDB::customers PSDrive : mydb PSProvider : System.Management.Automation.ProviderInfo PSIsContainer : True Data : System.Data.DataRow Name : Customers RowCount : 91 Columns :再次运行
Get-ChildItemcmdlet 以获取表的数据。(Get-ChildItem mydb:customers).Data以下是输出内容。
TABLE_CAT : C:\PS\northwind TABLE_SCHEM : TABLE_NAME : Customers TABLE_TYPE : TABLE REMARKS :现在用
Get-Itemcmdlet 在数据表的第 0 行检索这些项。Get-Item mydb:\customers\0以下是输出内容。
PSPath : AccessDB::customers\0 PSDrive : mydb PSProvider : System.Management.Automation.ProviderInfo PSIsContainer : False Data : System.Data.DataRow RowNumber : 0重用
Get-Item以获取第0行项目的数据。(Get-Item mydb:\customers\0).Data以下是输出内容。
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现在用
New-Itemcmdlet 向已有的表添加一行。 该Path参数指定了该行的完整路径,并且必须表示行数大于表中现有行数。 参数Type表示Row要指定要添加的类型。 最后,参数Value指定了该行的逗号分隔列值列表。New-Item -Path mydb:\Customers\3 -ItemType "Row" -Value "3,CustomerFirstName,CustomerLastName,CustomerEmailAddress,CustomerTitle,CustomerCompany,CustomerPhone, CustomerAddress,CustomerCity,CustomerState,CustomerZip,CustomerCountry"验证新项目作的正确性如下。
PS mydb:\> cd Customers PS mydb:\Customers> (Get-Item 3).Data以下是输出内容。
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