PowerShell 模块创作注意事项

本文档包含一些与如何创作模块以获得最佳性能相关的准则。

模块清单创作

不使用以下准则的模块清单可能会对常规 PowerShell 性能产生明显影响,即使模块未在会话中使用。

自动命令发现功能会分析每个模块,以识别模块导出的命令,而这种分析可能会消耗大量资源。 模块分析的结果是按用户缓存的,但在首次运行时缓存不可用,这在使用容器时是常见情况。 在模块分析期间,如果可以从清单中完全确定导出的命令,则可以避免对模块进行更昂贵的分析。

指引

  • 在模块清单中,不要在 AliasesToExportCmdletsToExportFunctionsToExport 条目中使用通配符。

  • 如果模块不导出特定类型的命令,请通过指定 @()在清单中显式指定此命令。 缺少此项或 $null 条目等效于指定通配符 *

应尽可能避免以下事项:

@{
    FunctionsToExport = '*'

    # Also avoid omitting an entry, it's equivalent to using a wildcard
    # CmdletsToExport = '*'
    # AliasesToExport = '*'
}

请改用:

@{
    FunctionsToExport = 'Format-Hex', 'Format-Octal'
    CmdletsToExport = @()  # Specify an empty array, not $null
    AliasesToExport = @()  # Also ensure all three entries are present
}

避免 CDXML

在决定如何实现模块时,有三个主要选择:

  • 二进制 (通常为 C#)
  • 脚本(PowerShell)
  • CDXML (封装 CIM 的 XML 文件)

如果加载模块的速度很重要,则 CDXML 大约比二进制模块慢一个数量级。

二进制模块加载速度最快,因为它会提前编译,并且可以使用 NGen 为每个计算机编译一次 JIT。

脚本模块通常比二进制模块加载速度要慢一点,因为 PowerShell 在编译和执行脚本之前必须分析脚本。

CDXML 模块通常比脚本模块慢得多,因为它必须首先分析 XML 文件,然后生成相当多的 PowerShell 脚本,然后对其进行分析和编译。