强烈建议的开发指南

本部分介绍编写 cmdlet 时应遵循的准则。 它们分为 cmdlet 设计指南和 cmdlet 代码编写指南。 你可能会发现,这些指南不适用于每种方案。 但是,如果它们适用,并且你未遵循这些指南,则用户在使用 cmdlet 时可能体验不佳。

设计准则

设计 cmdlet 时,应遵循以下准则,以确保使用 cmdlet 和其他 cmdlet 之间的用户体验一致。 找到适用于你的情况的设计准则时,请务必查看代码指南,了解类似的准则。

将特定名词用于 Cmdlet 名称 (SD01)

cmdlet 命名中使用的名词需要非常具体,以便用户可以发现 cmdlet。 使用产品名称的缩短版本为泛型名词(如"server")添加前缀。 例如,如果名词是指运行实例实例的服务器,Microsoft SQL Server"SQLServer"等名词。 将特定名词和已批准的谓词的简短列表相结合,用户可以快速发现和预测功能,同时避免 cmdlet 名称之间出现重复。

若要增强用户体验,为 cmdlet 名称选择的名词应该是单数的。 例如,使用 名称 Get-Process 而不是 Get-Processes 。 最好针对所有 cmdlet 名称遵循此规则,即使 cmdlet 可能会对多个项执行。

将 Pascal Case 用于 SD02 (Cmdlet)

对参数名称使用 Pascal 大小写。 换句话说,将谓词的第一个字母和名词中使用的所有术语大写。 例如“Clear-ItemProperty”。

SD03 (参数设计)

cmdlet 需要接收其必须操作的数据的参数,以及指示用于确定操作特征的信息的参数。 例如,cmdlet 可能有一个从管道接收数据的参数,并且该 cmdlet 可能有一个参数来指示 Name Force 可以强制该 cmdlet 执行其操作。 cmdlet 可以定义的参数数量没有限制。

使用标准参数名称

cmdlet 应使用标准参数名称,以便用户可以快速确定特定参数的含义。 如果需要更具体的名称,请使用标准参数名称,然后将更具体的名称指定为别名。 例如,该 cmdlet 具有一个参数,该参数具有一个 () ,以及一个 Get-Service Name ServiceName () 。 这两个术语都可用于指定 参数。

有关参数名称及其数据类型的信息,请参阅 Cmdlet 参数名称和功能准则

使用单数参数名称

避免对值为单个元素的参数使用复数名称。 这包括接受数组或列表的参数,因为用户可能只提供包含一个元素的数组或列表。

应仅在参数的值始终为多元素值的情况下使用复数参数名称。 在这些情况下,cmdlet 应验证是否提供了多个元素,如果未提供多个元素,则 cmdlet 应向用户显示警告。

将 Pascal 大小写用于参数名称

对参数名称使用 Pascal 大小写。 换句话说,将参数名称中每个单词的第一个字母(包括名称的第一个字母)大写。 例如,参数名称 ErrorAction 使用正确的大写。 以下参数名称使用不正确的大写:

  • errorAction
  • erroraction

接受选项列表的参数

有两种方法可以创建参数,该参数的值可以从一组选项中进行选择。

  • 定义枚举类型 (或使用指定有效值的) 枚举类型。 然后,使用 枚举类型创建该类型的参数。

  • ValidateSet 属性 添加到参数声明。 有关此属性详细信息,请参阅 ValidateSet 属性声明

对参数使用标准类型

若要确保与其他 cmdlet 保持一致,请尽可能将标准类型用于参数。 有关应该用于不同参数的类型详细信息,请参阅 标准 Cmdlet 参数名称和类型。 本主题提供了一些主题的链接,这些主题描述标准参数.NET Framework组的名称和类型,例如"活动参数"。

使用Strongly-Typed .NET Framework类型

参数应定义为.NET Framework类型,以提供更好的参数验证。 例如,限制为一组值中的一个值的参数应定义为枚举类型。 若要支持统一资源标识符 (URI) 值,请将 参数定义为 System.Uri 类型。 对于自由格式文本属性,请避免使用基本字符串参数。

使用一致的参数类型

如果多个 cmdlet 使用相同的参数,请始终使用相同的参数类型。 例如,如果参数 Process 是一个 cmdlet 的 System.Int16 类型,则不要将另一个 cmdlet 的 参数作为 Process System.Uint16 类型。

接受 True 和 False 的参数

如果参数仅采用 truefalse ,则将参数定义为 类型 System.Management.Automation.SwitchParameter。 switch 参数在命令 true 中指定时被视为 。 如果命令中未包含 参数,Windows PowerShell将 参数的值考虑为 false 。 不要定义布尔参数。

如果参数需要区分 3 个值:$true、$false和"未指定",则定义类型为 Nullable 的参数 <bool> 。 当 cmdlet 可以修改对象的布尔属性时,通常会需要第三个"未指定"值。 在这种情况下,"未指定"表示不更改属性的当前值。

支持参数数组

通常,用户必须对多个参数执行相同的操作。 对于这些用户,cmdlet 应接受数组作为参数输入,以便用户可以将参数作为参数Windows PowerShell参数。 例如 ,Get-Process cmdlet 对标识要检索的进程名称的字符串使用数组。

支持 PassThru 参数

默认情况下,许多修改系统的 cmdlet(如 Stop-Process cmdlet)充当对象的"接收器",不返回结果。 这些 cmdlet 应实现 PassThru 参数以强制 cmdlet 返回对象。 指定 PassThru 参数时,cmdlet 通过使用对 System.Management.Automation.Cmdlet.WriteObject 方法的调用返回对象。 例如,以下命令停止 Calc 进程,将结果进程传递给管道。

Stop-Process calc -passthru

在大多数情况下,"添加"、"设置"和"新建"cmdlet 应支持 PassThru 参数。

支持参数集

cmdlet 旨在实现单个目的。 但是,通常有不止一种方法来描述操作或操作目标。 例如,进程可能按名称、标识符或进程对象进行标识。 cmdlet 应支持其目标的所有合理表示形式。 通常,cmdlet 通过指定参数集来满足此要求 (称为一起) 的参数集。 单个参数可以属于任意数目的参数集。 有关参数集详细信息,请参阅 Cmdlet 参数集

指定参数集时,仅将设置中的一个参数设置为 ValueFromPipeline。 若要详细了解如何声明 Parameter 属性,请参阅 ParameterAttribute 声明

使用参数集时,默认参数集由 Cmdlet 属性定义。 默认参数集应包含最有可能在交互式会话中使用的Windows PowerShell参数。 若要详细了解如何声明 Cmdlet 属性,请参阅 CmdletAttribute 声明

向用户反馈 (SD04)

使用本部分中的准则为用户提供反馈。 此反馈允许用户了解系统中发生的情况,并做出更好的管理决策。

使用Windows PowerShell运行时,用户通过设置首选项变量来指定如何处理每次调用方法 Write 的输出。 用户可以设置多个首选项变量,包括一个确定系统是否应该显示信息的变量,以及一个确定系统是否应该在采取进一步操作之前查询用户的变量。

支持 WriteWarning、WriteVerbose 和 WriteDebug 方法

当 cmdlet 即将执行可能会产生意外结果的操作时,cmdlet 应调用 System.Management.Automation.Cmdlet.WriteWarning 方法。 例如,如果 cmdlet 即将覆盖只读文件,则 cmdlet 应调用此方法。

当用户需要 cmdlet 正在执行哪些操作的详细信息时,cmdlet 应调用 System.Management.Automation.Cmdlet.WriteVerbose 方法。 例如,如果 cmdlet 作者认为某些方案可能需要有关 cmdlet 执行的操作的详细信息,则 cmdlet 应调用此信息。

当开发人员或产品支持工程师必须了解已损坏 cmdlet 操作时,该 cmdlet 应调用 WriteDebug 方法。 Cmdlet 不需要在调用WriteVerbose方法的同一代码中调用WriteDebug方法,因为该 Debug 参数会同时提供这两种类型的信息,这是因为该参数提供了这两个信息集。

支持对耗时较长的操作的 WriteProgress

需要很长时间才能完成并且无法在后台运行的 Cmdlet 操作应该支持通过定期调用 WriteProgress 方法来报告进度。

使用宿主接口

有时,cmdlet 必须直接与用户通信,而不是使用 系统管理 类支持的各种写入或应方法。 在这种情况下,该 cmdlet 应派生自 PSCmdlet 类,并使用 PSCmdlet * 属性来实现。 此属性支持不同级别的通信类型,包括 PromptForChoice、Prompt 和 WriteLine/ReadLine 类型。 在最具体的层面上,它还提供了读取和写入单个密钥并处理缓冲区的方法。

除非 cmdlet 专门用于生成图形用户界面 (GUI) ,否则它不应使用 PSCmdlet * 属性来绕过该主机。 为生成 GUI 而设计的 cmdlet 的一个示例是 " " cmdlet。

备注

Cmdlet 不应使用 系统控制台 API。

(SD05 创建 Cmdlet 帮助文件)

对于每个 cmdlet 程序集,创建一个 Help.xml 文件,其中包含有关该 cmdlet 的信息。 此信息包括 cmdlet 的说明、cmdlet 的参数说明、cmdlet 使用的示例等。

代码准则

编写 cmdlet 时应遵循以下准则,以确保在使用 cmdlet 和其他 cmdlet 之间保持一致的用户体验。 如果你发现适用于你的情况的代码准则,请务必查看类似指导原则的设计指南。

编码参数 (SC01)

通过声明使用 parameter 特性修饰的 cmdlet 类的公共属性来定义参数。 参数不一定是 cmdlet 的派生 .NET Framework 类的静态成员。 有关如何声明 参数 属性的详细信息,请参阅 参数属性声明

支持 Windows PowerShell 路径

Windows PowerShell 路径是用于规范化对命名空间的访问的机制。 将 Windows PowerShell 路径分配给 cmdlet 中的参数时,用户可以定义一个自定义 "驱动器",它充当特定路径的快捷方式。 当用户指定此类驱动器时,可以通过一致的方式使用存储的数据(如注册表中的数据)。

如果你的 cmdlet 允许用户指定文件或数据源,则它应定义类型为 system.string的参数。 如果支持多个驱动器,则类型应为数组。 参数的名称应为 Path ,别名为 PSPath 。 此外, Path 参数应支持通配符。 如果不需要支持通配符,请定义 LiteralPath 参数。

如果 cmdlet 读取或写入的数据必须是文件,则该 cmdlet 应接受 Windows PowerShell 路径输入,并且该 cmdlet 应使用Sessionstate属性将 Windows PowerShell 路径转换为文件系统可识别的路径。 具体的机制包括以下方法:

如果 cmdlet 读取或写入的数据只是一组字符串而不是文件,则该 cmdlet 应该使用提供程序内容信息 (Content 成员) 进行读取和写入。 此信息是从 CmdletProvider. InvokeProvider 属性获取的。 这些机制允许其他数据存储区参与数据的读取和写入。

支持通配符

如果可能,cmdlet 应支持通配符。 对通配符的支持出现在 cmdlet 中的多个位置 (尤其是在参数采用字符串来标识一组对象) 中的一个对象时。 例如, Stop-Proc StopProc 教程 中的示例 cmdlet 定义了一个 Name 参数,用于处理表示进程名称的字符串。 此参数支持通配符,使用户能够轻松地指定要停止的进程。

当支持通配符时,cmdlet 操作通常会生成一个数组。 有时,如果支持数组,则没有意义,因为用户一次只能使用一个项。 例如, 设置位置 cmdlet 不需要支持数组,因为用户仅设置一个位置。 在这种情况下,该 cmdlet 仍支持通配符,但会强制将分辨率转换为单一位置。

有关通配符模式的详细信息,请参阅 在 Cmdlet 参数中支持通配符

定义对象

本部分包含有关为 cmdlet 定义对象以及扩展现有对象的准则。

定义标准成员

定义标准成员以在自定义 types.ps1xml 文件中扩展对象类型 (使用 Windows PowerShell types.ps1xml 文件作为模板) 。 标准成员由名称为 PSStandardMembers 的节点定义。 这些定义允许其他 cmdlet 和 Windows PowerShell 运行时以一致的方式处理对象。

定义要用作参数的 ObjectMembers

如果要为 cmdlet 设计对象,请确保其成员直接映射到将使用它的 cmdlet 的参数。 通过此映射,可轻松地将对象发送到管道,并将其从一个 cmdlet 传递到另一个 cmdlet。

cmdlet 返回的预先存在的 .NET Framework 对象常常缺少脚本开发人员或用户所需的一些重要或便捷的成员。 这些缺少的成员对于显示和创建正确的成员名称尤其重要,这样就可以正确地将对象传递到管道。 创建自定义 types.ps1xml 文件来记录这些必需成员。 创建此文件时,建议采用以下命名约定: <Your_Product_Name>。Types.ps1xml。

例如,你可以将 Mode 脚本属性添加到 FileInfo 类型,以更清晰地显示文件的属性。 此外,您还可以向 system.string Count 类型添加 alias 属性,以允许 (的属性名称的使用一致,而不是 Length) 。

实现 IComparable 接口

在所有输出对象上实现 system.icomparable 接口。 这样,就可以轻松地将输出对象输送到各种排序和分析 cmdlet 中。

更新显示信息

如果对象的显示未提供预期结果,请创建自定义 <YourProductName> 。该对象的 types.ps1xml 文件。

支持定义良好的管道输入 (SC02)

实现管道的中间

实现一个 cmdlet,假设它将从管道的中间调用 (即,其他 cmdlet 将生成其输入或使用其输出) 。 例如,你可能会认为该 Get-Process cmdlet 会生成数据,因为它只是管道中的第一个 cmdlet。 但是,由于此 cmdlet 是为管道的中间设计的,因此此 cmdlet 允许管道中的上一个 cmdlet 或数据指定要检索的进程。

支持管道中的输入

在 cmdlet 的每个参数集中,至少包括一个支持管道输入的参数。 支持管道输入允许用户检索数据或对象,以将其发送到正确的参数集,并将结果直接传递给 cmdlet。

如果 参数 属性 ValueFromPipeline ValueFromPipelineByPropertyName 在其声明中包含关键字、关键字属性或同时包含这两个关键字,则参数接受来自管道的输入。 如果参数集中的参数均 ValueFromPipeline 不支持或 ValueFromPipelineByPropertyName 关键字,则无法有意义地将 cmdlet 置于另一个 cmdlet 之后,因为它将忽略任何管道输入。

支持 ProcessRecord 方法

若要接受来自管道中前面的 cmdlet 的所有记录,cmdlet 必须实现 ProcessRecord 方法。 Windows PowerShell 多次调用此方法,将每条记录发送到你的 cmdlet。

将单个记录写入管道 (SC03)

当 cmdlet 返回对象时,cmdlet 应在生成对象时立即写入它们。 Cmdlet 不应包含它们,以便将它们缓冲到合并的数组中。 作为输入接收对象的 cmdlet 将能够处理、显示或处理并显示输出对象,而无需延迟。 一个 cmdlet,它一次生成一个输出对象应调用 WriteObject 方法。 一个 cmdlet,它以批处理方式生成输出对象 (例如,因为基础 API 返回输出对象的数组) 应调用 WriteObject 方法,并将其第二个参数设置为 true

将 Cmdlet Case-Insensitive 和 Case-Preserving (SC04)

默认情况下,Windows PowerShell 本身不区分大小写。 不过,由于它处理许多预先存在的系统,因此 Windows PowerShell 确实会为操作和兼容性提供便利。 换而言之,如果字符以大写字母形式提供,Windows PowerShell 会将其保留为大写字母。 为了使系统正常工作,cmdlet 需要遵循此约定。 如果可能,它应以不区分大小写的方式运行。 但是,它应保留在命令中或在管道中随后出现的 cmdlet 的原始事例。

另请参阅

必需的开发指南

咨询性的开发指南

编写 Windows PowerShell Cmdlet