PowerShellGallery 发布指南和最佳做法

本文介绍Microsoft团队使用的建议步骤,以确保将广泛采用发布到 PowerShell 库的包,并根据 PowerShell 库如何处理清单数据和大量 PowerShell 库用户的反馈,为用户提供高价值。 遵循这些准则发布的包更有可能安装、信任和吸引更多用户。

下面提供了一些指南,这些指南介绍了什么是好的 PowerShell 库包、什么是可选清单设置、使用初始审阅者的反馈改进代码,以及 Powershell 脚本分析器、模块版本控制、文档、测试和示例,以了解如何使用共享的内容。 本文档的大部分内容都遵循 高质量 DSC 资源模块发布指南。

有关将包发布到 PowerShell 库的机制,请参阅 创建和发布包

欢迎就这些准则提供反馈。 如果有反馈,请在 GitHub 文档存储库中提出问题。

发布包的最佳做法

以下最佳做法是 PowerShell 库项的用户所说的重要内容,并按名义优先级顺序列出。 遵循这些准则的包更有可能被其他人下载和采用。

  • 使用 PSScriptAnalyzer
  • 包括文档和示例
  • 响应反馈
  • 提供模块而不是脚本
  • 提供指向项目网站的链接
  • 使用兼容的 PSEdition(s) 和平台标记包
  • 将测试包含在模块中
  • 包括和/或指向许可条款的链接
  • 对代码进行签名
  • 遵循 SemVer 版本控制指南
  • 使用通用 PowerShell 库标记中所述的通用标记
  • 使用本地存储库测试发布
  • 使用 PowerShellGet 发布

下面各节简要介绍了其中每个内容。

使用 PSScriptAnalyzer

PSScriptAnalyzer 是一种适用于 PowerShell 代码的免费静态代码分析工具。 PSScriptAnalyzer 将识别 PowerShell 代码中看到的最常见问题,以及有关如何解决此问题的建议。 该工具易于使用,并将问题分类为错误(严重,必须解决)、警告(需要审查并应解决)和信息(值得查看最佳做法)。 将使用 PSScriptAnalyzer扫描发布到 PowerShell 库的所有包,并且任何错误都将报告回所有者,必须解决。

最佳做法是使用 -Recurse-Severity 警告运行 Invoke-ScriptAnalyzer

查看结果,并确保:

  • 文档中已更正或解决所有错误。
  • 检查所有警告,并在适用情况下解决。

强烈建议从 PowerShell 库下载包的用户 PSScriptAnalyzer 并评估所有错误和警告。 如果用户看到 PSScriptAnalyzer报告了错误,用户很可能与包所有者联系。 如果包保留标记为错误的代码有令人信服的理由,请将该信息添加到文档,以避免多次回答相同的问题。

包括文档和示例

文档和示例是确保用户能够利用任何共享代码的最佳方法。

文档是发布到 PowerShell 库的包中包含的最有帮助的事情。 用户通常会绕过没有文档的包,因为替代方法是阅读代码以了解包是什么以及如何使用它。 有几篇文章介绍如何提供 PowerShell 包的文档,包括:

  • 有关如何提供帮助的指南 如何编写 Cmdlet 帮助
  • 创建 cmdlet 帮助,这是任何 PowerShell 脚本、函数或 cmdlet 的最佳方法。 有关如何创建 cmdlet 帮助的信息,请从 如何编写 Cmdlet 帮助开始。 若要在脚本中添加帮助,请参阅 关于基于批注的帮助
  • 许多模块还包含文本格式的文档,例如 MarkDown 文件。 当 GitHub 中有项目网站(其中 Markdown 是一种广泛使用的格式)时,这尤其有用。 最佳做法是使用 GitHub 风格的 Markdown

示例显示用户如何使用包。 许多开发人员会说,他们在文档前查看示例,了解如何使用某些内容。 最佳示例类型显示了基本用法,以及模拟的现实用例,并且代码已得到很好的注释。 发布到 PowerShell 库的模块示例应位于模块根目录下的示例文件夹中。

PSDscResource 模块Examples\RegistryResource 文件夹下,可以找到一个很好的示例模式。 每个文件的顶部有四个示例用例,其中简要说明记录了所演示的内容。

管理依赖项

请务必在模块清单中指定模块所依赖的模块。 这样,最终用户就无需担心安装依赖的模块的正确版本。 若要指定依赖模块,应在模块清单中使用所需的模块字段。 这将在导入模块之前将列出的任何模块加载到全局环境中,除非这些模块已加载。 例如,某些模块可能已由其他模块加载。 还可以使用 RequiredVersion 字段(而不是 ModuleVersion 字段)指定要加载的特定版本。 使用 ModuleVersion时,它将加载可用的最新版本(至少指定的版本)。 如果不使用 RequiredVersion 字段,若要指定特定版本,请务必监视所需模块的版本更新。 请务必注意可能影响模块用户体验的任何中断性变更。

Example: RequiredModules = @(@{ModuleName="myDependentModule"; ModuleVersion="2.0"; Guid="cfc45206-1e49-459d-a8ad-5b571ef94857"})

Example: RequiredModules = @(@{ModuleName="myDependentModule"; RequiredVersion="1.5"; Guid="cfc45206-1e49-459d-a8ad-5b571ef94857"})

响应反馈

对反馈做出正确响应的包所有者受到社区的高度评价。 提供建设性反馈的用户对于响应非常重要,因为他们对程序包感兴趣,以试图帮助改进它。

PowerShell 库中提供了一种反馈方法:

  • 联系人所有者:这允许用户向包所有者发送电子邮件。 作为包所有者,请务必监视与 PowerShell 库包一起使用的电子邮件地址,并响应引发的问题。 此方法的一个缺点是,只有用户和所有者才能看到通信,因此所有者可能需要多次回答相同的问题。

社区赞赏对反馈做出建设性回应的业主。 使用报表中的机会请求更多信息。 如果需要,请提供解决方法,或确定更新是否修复了问题。

如果从其中任一通信渠道观察到不当行为,请使用 PowerShell 库的报告滥用功能联系库管理员。

模块与脚本

与其他用户共享脚本非常出色,并提供了有关如何解决他们可能遇到的问题的示例。 问题是,PowerShell 库中的脚本是单个文件,没有单独的文档、示例和测试。

PowerShell 模块具有文件夹结构,允许包中包含多个文件夹和文件。 模块结构允许包括我们列为最佳做法的其他包:cmdlet 帮助、文档、示例和测试。 最大的缺点是模块内的脚本必须公开并用作函数。 有关如何创建模块的信息,请参阅 编写 Windows PowerShell 模块

在某些情况下,脚本为用户提供更好的体验,尤其是 DSC 配置。 DSC 配置的最佳做法是将配置发布为包含文档、示例和测试的随附模块的脚本。 该脚本使用 RequiredModules = @(Name of the Module)列出随附的模块。 此方法可用于任何脚本。

遵循其他最佳做法的独立脚本为其他用户提供实际价值。 在将脚本发布到 PowerShell 库时,强烈建议提供基于注释的文档和指向项目网站的链接。

项目网站是发布者可以直接与其 PowerShell 库包的用户进行交互的地方。 用户更喜欢提供此包的包,因为它允许他们更轻松地获取有关包的信息。 PowerShell 库中的许多包都是在 GitHub 中开发的,其他包由具有专用 Web 状态的组织提供。 每个项目都可以视为项目网站。

添加链接是通过在清单的 PSData 部分中包括 ProjectURI 来完成的,如下所示:

  # A URL to the main website for this project.
  ProjectUri = 'https://github.com/powershell/powershell'

提供 ProjectURI 后,PowerShell 库将包含指向包页面左侧的项目网站的链接。

使用兼容的 PSEdition(s) 和平台标记包

使用以下标记向用户演示哪些包适用于其环境:

  • PSEdition_Desktop:与 Windows PowerShell 兼容的包
  • PSEdition_Core:与 PowerShell 6 及更高版本兼容的包
  • Windows:与 Windows 操作系统兼容的包
  • Linux:与 Linux 操作系统兼容的包
  • MacOS:与 Mac 操作系统兼容的包

通过将包标记为兼容平台(s),它将包含在搜索结果左窗格中的库搜索筛选器中。 如果在 GitHub 上托管包,则标记包时,还可以利用我们的 PowerShell 库兼容性防护兼容性防护示例

包括测试

使用开源代码包括测试对用户很重要,因为它为用户提供验证内容保证,并提供有关代码工作原理的信息。 它还允许用户确保在修改代码以适应其环境时不会破坏原始功能。

强烈建议编写测试以利用 Pester 测试框架,该框架专为 PowerShell 设计。 Pester 在 GitHubPowerShell 库中提供,并随附在 Windows 10、Windows Server 2016、WMF 5.0 和 WMF 5.1 中。

GitHub 中的 Pester 项目网站 包括有关编写 Pester 测试的良好文档,从入门到最佳做法。

高质量资源模块文档中列出了测试覆盖率的目标,建议使用 70 个% 单元测试代码覆盖率。

发布到 PowerShell 库的所有包都必须指定许可条款,或受 使用条款 中包含的许可证的约束,附件 A。指定其他许可证的最佳方法是使用 PSData中的 LicenseURI 提供指向许可证的链接。 有关详细信息,请参阅 包清单和库 UI

PrivateData = @{
    PSData = @{

        # Tags applied to this module. These help with module discovery in online galleries.
        Tags = @('.net','acl','active-directory')

        # A URL to the license for this module.
        LicenseUri = 'http://www.apache.org/licenses/LICENSE-2.0'

对代码进行签名

代码签名为用户提供了发布包的最高保证级别,并且获取的代码副本正是发布者发布的。 若要了解有关代码签名的详细信息,请参阅 代码签名简介。 PowerShell 支持通过两种主要方法验证代码签名:

  • 签名脚本文件
  • 对模块进行目录签名

对 PowerShell 文件进行签名是一种成熟的方法,用于确保所执行的代码是由可靠源生成的,并且尚未修改。 有关如何对 PowerShell 脚本文件进行签名的详细信息,请参阅 关于签名 一文。 在概述中,可以将签名添加到 PowerShell 在加载脚本时验证的任何 .PS1 文件。 可以使用 执行策略 cmdlet 限制 PowerShell,以确保使用已签名的脚本。

目录签名模块是 5.1 版中添加到 PowerShell 的功能。 目录 Cmdlet 一文中介绍了如何对模块进行签名。 在概述中,目录签名是通过创建目录文件来完成的,该文件包含模块中每个文件的哈希值,然后对该文件进行签名。

PowerShellGetPublish-ModuleInstall-ModuleUpdate-Module cmdlet 将检查签名以确保签名有效,然后确认每个包的哈希值是否与目录中的内容匹配。 Save-Module 不验证签名。 如果系统上安装了以前版本的模块,Install-Module 将确认新版本的签名机构是否与以前安装的版本匹配。 如果未对包进行目录签名,Install-ModuleUpdate-Module 将在 .PSD1 文件上使用签名。 目录签名适用于,但不替换签名脚本文件。 PowerShell 不会在模块加载时验证目录签名。

遵循 SemVer 版本控制指南

SemVer 是一种公共约定,描述如何构建和更改版本,以便轻松解释更改。 包的版本必须包含在清单数据中。

  • 版本应结构化为三个数字块,以句点分隔,如 0.1.14.11.192中所示。
  • 0 开始的版本表示包尚未准备好生产,并且第一个数字应以 0 开头(如果这是使用的唯一数字)。
  • 第一个数字(1.9.99992.0.0)中的更改表示版本之间的重大更改和中断性变更。
  • 对第二个数字(1.11.2)的更改表示功能级别更改,例如向模块添加新 cmdlet。
  • 第三个数字的更改表示非中断性变更,例如新参数、更新的示例或新测试。
  • 列出版本时,PowerShell 会将版本排序为字符串,因此 1.01.0 将被视为大于 1.001.0

PowerShell 是在发布 SemVer 之前创建的,因此它为 SemVer 的大多数但并非所有元素提供支持,特别是:

  • 它不支持版本号中的预发行版字符串。 当发布者希望在提供版本 1.0.0后提供新版本的预览版本时,这非常有用。 在 PowerShell 库的未来版本中支持此功能,PowerShellGet cmdlet。
  • PowerShell 和 PowerShell 库允许版本字符串包含 1、2 和 4 段。 许多早期模块没有遵循准则,来自Microsoft的产品版本包括生成信息作为第四个数字块(例如 5.1.14393.1066)。 从版本控制的角度来看,这些差异将被忽略。

使用本地存储库进行测试

PowerShell 库不是测试发布过程的目标。 测试发布到 PowerShell 库的端到端过程的最佳方式是设置和使用自己的本地存储库。 这可以通过几种方法完成,包括:

  • 使用 GitHub 中的 PS 专用库项目 设置本地 PowerShell 库实例。 此预览项目将帮助你设置可控制并用于测试的 PowerShell 库实例。
  • 设置 内部 Nuget 存储库。 这将需要更多的工作来设置,但将具有验证更多要求的优势,特别是验证 API 密钥的使用,以及发布时目标中是否存在依赖项。
  • 将文件共享设置为测试 存储库。 这很容易设置,但由于它是文件共享,因此不会进行上述验证。 在这种情况下,一个潜在的优点是文件共享不会检查所需的 API 密钥,因此可以使用用于发布到 PowerShell 库的相同密钥。

使用这些解决方案中的任何一种,请使用 Register-PSRepository 来定义新的 存储库-Repository 参数中用于 Publish-Module

有关测试发布的其他一点:在操作团队的帮助下,无法删除发布到 PowerShell 库的任何包,这些操作团队将确认任何内容都依赖于要发布的包。 因此,我们不支持 PowerShell 库作为测试目标,并将联系任何这样做的发布者。

使用 PowerShellGet 发布

强烈建议发布者在使用 PowerShell 库时使用 Publish-ModulePublish-Script cmdlet。 已创建 PowerShellGet,以帮助避免记住有关从 PowerShell 库安装和发布到 PowerShell 库的重要详细信息。 有时,发布者已选择跳过 PowerShellGet,并使用 NuGet 客户端,或 PackageManagement cmdlet,而不是 Publish-Module。 有许多细节很容易错过,这会导致各种支持请求。

如果有理由无法使用 Publish-ModulePublish-Script,请告知我们。 在 PowerShellGet GitHub 存储库中提出问题,并提供导致你选择 NuGetPackageManagement的详细信息。

我们为发布到 PowerShell 库的包找到的最成功方法是:

  • 在开源项目站点中执行初始开发。 PowerShell 团队使用 GitHub。
  • 使用审阅者和 PowerShell 脚本分析器 的反馈,使代码处于稳定状态。
  • 包括文档,以便其他人知道如何使用你的工作。
  • 使用本地存储库测试发布操作。
  • 将稳定版本或 Alpha 版本发布到 PowerShell 库,确保包含文档并链接到项目网站。
  • 收集反馈并循环访问项目站点中的代码,然后将稳定更新发布到 PowerShell 库。
  • 在项目和模块中添加示例和 Pester 测试。
  • 确定是否要对包进行代码签名。
  • 当你觉得项目准备好在生产环境中使用时,将 1.0.0 版本发布到 PowerShell 库。
  • 继续根据用户输入收集反馈并循环访问代码。