如何编写 PowerShell 二进制模块

二进制模块可以是包含 cmdlet 类的任何程序集(.dll)。 默认情况下,导入二进制模块时,将导入程序集中的所有 cmdlet。 但是,可以通过创建根模块为程序集的模块清单来限制导入的 cmdlet。 (例如,清单的 CmdletsToExport 密钥可用于仅导出所需的 cmdlet。此外,二进制模块可以包含其他文件、目录结构以及单个 cmdlet 无法提供的其他有用管理信息片段。

以下过程介绍如何创建和安装 PowerShell 二进制模块。

如何创建和安装 PowerShell 二进制模块

  1. 使用所需的功能创建二进制 PowerShell 解决方案(如用 C# 编写的 cmdlet),并确保其正常运行。

    从代码的角度来看,二进制模块的核心只是 cmdlet 程序集。 事实上,在加载和卸载方面,PowerShell 会将单个 cmdlet 程序集视为模块,开发人员无需再做任何工作。 有关编写 cmdlet 的详细信息,请参阅 编写 Windows PowerShell Cmdlet

  2. 如有必要,请创建解决方案的其余部分:(其他 cmdlet、XML 文件等),并使用模块清单对其进行描述。

    除了在解决方案中描述 cmdlet 程序集外,模块清单还可以描述如何导出和导入模块、将公开哪些 cmdlet 以及哪些附加文件将进入模块。 不过,如前所述,PowerShell 可以像模块一样处理二进制 cmdlet,无需额外工作。 因此,模块清单主要用于将多个文件合并到单个包中,或用于显式控制给定程序集的发布。 有关详细信息,请参阅 如何编写 PowerShell 模块清单

    以下代码是一个极其简单的 C# 代码块,其中包含同一文件中的三个 cmdlet,可用作模块。

    using System.Management.Automation;           // Windows PowerShell namespace.
    
    namespace ModuleCmdlets
    {
      [Cmdlet(VerbsDiagnostic.Test,"BinaryModuleCmdlet1")]
      public class TestBinaryModuleCmdlet1Command : Cmdlet
      {
        protected override void BeginProcessing()
        {
          WriteObject("BinaryModuleCmdlet1 exported by the ModuleCmdlets module.");
        }
      }
    
      [Cmdlet(VerbsDiagnostic.Test, "BinaryModuleCmdlet2")]
      public class TestBinaryModuleCmdlet2Command : Cmdlet
      {
          protected override void BeginProcessing()
          {
              WriteObject("BinaryModuleCmdlet2 exported by the ModuleCmdlets module.");
          }
      }
    
      [Cmdlet(VerbsDiagnostic.Test, "BinaryModuleCmdlet3")]
      public class TestBinaryModuleCmdlet3Command : Cmdlet
      {
          protected override void BeginProcessing()
          {
              WriteObject("BinaryModuleCmdlet3 exported by the ModuleCmdlets module.");
          }
      }
    
    }
    
  3. 打包解决方案,并将包保存到 PowerShell 模块路径中的某个位置。

    PSModulePath 全局环境变量描述 PowerShell 用于查找模块的默认路径。 例如,在系统上保存模块的常见路径 %SystemRoot%\Users\<user>\Documents\WindowsPowerShell\Modules\<moduleName>。 如果不使用默认路径,则需要在安装过程中显式声明模块的位置。 请务必创建一个文件夹来保存模块,因为可能需要该文件夹来存储解决方案的多个程序集和文件。

    请注意,从技术上来说,无需在 PSModulePath 上安装模块 - 这些只是 PowerShell 将查找模块的默认位置。 但是,最佳做法是这样做,除非有充分的理由将模块存储在其他位置。 有关详细信息,请参阅 安装 PowerShell 模块about_PSModulePath

  4. 通过调用 Import-Module将模块导入 PowerShell。

    调用 Import-Module 会将模块加载到活动内存中。 如果使用 PowerShell 3.0 及更高版本,只需在代码中调用模块的名称也会导入它;有关详细信息,请参阅 导入 PowerShell 模块

将管理单元程序集导入为模块

管理单元程序集中存在的 Cmdlet 和提供程序可以作为二进制模块加载。 当管理单元程序集作为二进制模块加载时,管理单元中的 cmdlet 和提供程序可供用户使用,但程序集中的管理单元类将被忽略,并且未注册管理单元。 因此,Windows PowerShell 提供的管理单元 cmdlet 无法检测管理单元,即使该 cmdlet 和提供程序可用于会话。

此外,无法将管理单元引用的任何格式或类型文件导入为二进制模块的一部分。 若要导入格式设置和类型文件,必须创建模块清单。 请参阅 如何编写 PowerShell 模块清单

另请参阅

编写 Windows PowerShell 模块