安装 PowerShell 模块

创建 PowerShell 模块后,你可能需要在系统上安装该模块,以便你或其他人可以使用它。 一般来说,这包括将模块文件(即 .psm1或二进制程序集、模块清单和任何其他关联文件)复制到该计算机上的目录。 对于非常小型的项目,这可能与使用 Windows 资源管理器将文件复制和粘贴到单个远程计算机上一样简单;但是,对于较大的解决方案,你可能希望使用更复杂的安装过程。 无论如何将模块安装到系统上,PowerShell 都可以使用多种技术,让用户查找和使用模块。 因此,安装的主要问题是确保 PowerShell 能够找到模块。 有关其他信息,请参阅导入 PowerShell 模块

用于安装模块的规则

以下信息涉及所有模块,包括为自己的用途创建的模块、从其他参与方获取的模块以及分发给其他人的模块。

在 PSModulePath 中安装模块

尽可能在 PSModulePath 环境变量中列出的路径中安装所有模块,或将模块路径添加到 PSModulePath 环境变量值。

PSModulePath 环境变量($Env:PSModulePath)包含 Windows PowerShell 模块的位置。 Cmdlet 依赖于此环境变量的值来查找模块。

默认情况下,PSModulePath 环境变量值包含以下系统和用户模块目录,但你可以添加和编辑该值。

  • $PSHOME\Modules%windir%\System32\WindowsPowerShell\v1.0\Modules

    警告

    此位置是为随 Windows 附带的模块保留的。 不要将模块安装到此位置。

  • $HOME\Documents\WindowsPowerShell\Modules%HOMEDRIVE%%HOMEPATH%\Documents\WindowsPowerShell\Modules

  • $Env:ProgramFiles\WindowsPowerShell\Modules%ProgramFiles%\WindowsPowerShell\Modules

    若要获取 PSModulePath 环境变量的值,请使用以下命令之一。

    $Env:PSModulePath
    [Environment]::GetEnvironmentVariable("PSModulePath")
    

    若要将模块路径添加到 PSModulePath 环境变量值的模块路径,请使用以下命令格式。 此格式使用 System.Environment 类的 SetEnvironmentVariable 方法对 PSModulePath 环境变量进行与会话无关的更改。

    #Save the current value in the $p variable.
    $p = [Environment]::GetEnvironmentVariable("PSModulePath")
    
    #Add the new path to the $p variable. Begin with a semi-colon separator.
    $p += ";C:\Program Files (x86)\MyCompany\Modules\"
    
    #Add the paths in $p to the PSModulePath value.
    [Environment]::SetEnvironmentVariable("PSModulePath",$p)
    

    重要

    将路径添加到 PSModulePath后,应广播有关更改的环境消息。 广播更改允许其他应用程序(如 shell)选取更改。 若要广播更改,请让产品安装代码发送一条 WM_SETTINGCHANGE 消息,其中 lParam 设置为字符串“Environment”。 请确保在模块安装代码更新 PSModulePath后发送消息。

使用正确的模块目录名称

格式正确的模块是存储在与模块目录中至少一个文件的基名称相同的目录中的模块。 如果模块格式不正确,Windows PowerShell 无法将其识别为模块。

文件的“基名称”是没有文件扩展名的名称。 在格式正确的模块中,包含模块文件的目录的名称必须与模块中至少一个文件的基名称匹配。

例如,在示例 Fabrikam 模块中,包含模块文件的目录名为“Fabrikam”,至少一个文件具有“Fabrikam”基名称。 在这种情况下,Fabrikam.psd1 和 Fabrikam.dll 都具有“Fabrikam”基名称。

C:\Program Files
  Fabrikam Technologies
    Fabrikam Manager
      Modules
        Fabrikam
          Fabrikam.psd1 (module manifest)
          Fabrikam.dll (module assembly)

安装不正确的影响

如果模块格式不正确,并且其位置未包含在 PSModulePath 环境变量的值中,则 Windows PowerShell 的基本发现功能(如以下)不起作用。

  • 模块自动加载功能无法自动导入模块。

  • Get-Module cmdlet 的 ListAvailable 参数找不到该模块。

  • Import-Module cmdlet 找不到该模块。 若要导入模块,必须提供根模块文件或模块清单文件的完整路径。

    除非将模块导入到会话中,否则其他功能(如以下)不起作用。 在 PSModulePath 环境变量中格式良好的模块中,即使模块未导入到会话中,这些功能也能正常工作。

  • Get-Command cmdlet 无法在模块中找到命令。

  • Update-HelpSave-Help cmdlet 无法更新或保存模块的帮助。

  • Show-Command cmdlet 找不到并在模块中显示命令。

    模块中的命令在 Windows PowerShell 集成脚本环境(ISE)中的 Show-Command 窗口中缺失。

在何处安装模块

本部分介绍文件系统中用于安装 Windows PowerShell 模块的位置。 位置取决于模块的使用方式。

为特定用户安装模块

如果你创建自己的模块或从另一方(例如 Windows PowerShell 社区网站)获取模块,并且希望该模块仅适用于用户帐户,请在用户特定的模块目录中安装该模块。

$HOME\Documents\WindowsPowerShell\Modules\<Module Folder>\<Module Files>

默认情况下,用户特定的 Modules 目录将添加到 PSModulePath 环境变量的值。

在 Program Files 中为所有用户安装模块

如果希望一个模块可供计算机上的所有用户帐户使用,请在 Program Files 位置安装该模块。

$Env:ProgramFiles\WindowsPowerShell\Modules\<Module Folder>\<Module Files>

注释

默认情况下,程序文件位置将添加到 WINDOWS PowerShell 4.0 及更高版本中 PSModulePath 环境变量的值。 对于早期版本的 Windows PowerShell,可以手动创建 Program Files 位置(%ProgramFiles%\WindowsPowerShell\Modules),并将此路径添加到 PSModulePath 环境变量,如前所述。

在产品目录中安装模块

如果要将模块分发给其他参与方,请使用上述默认的程序文件位置,或创建自己特定于公司或特定于产品的 %ProgramFiles% 目录子目录。

例如,虚构公司的 Fabrikam Technologies 正在为其 Fabrikam Manager 产品交付 Windows PowerShell 模块。 其模块安装程序在 Fabrikam Manager 产品子目录中创建 Modules 子目录。

C:\Program Files
  Fabrikam Technologies
    Fabrikam Manager
      Modules
        Fabrikam
          Fabrikam.psd1 (module manifest)
          Fabrikam.dll (module assembly)

若要启用 Windows PowerShell 模块发现功能以查找 Fabrikam 模块,Fabrikam 模块安装程序会将模块位置添加到 PSModulePath 环境变量的值。

$p = [Environment]::GetEnvironmentVariable("PSModulePath")
$p += ";C:\Program Files\Fabrikam Technologies\Fabrikam Manager\Modules\"
[Environment]::SetEnvironmentVariable("PSModulePath",$p)

在通用文件目录中安装模块

如果模块由产品的多个组件或产品的多个版本使用,请在 %ProgramFiles%\Common Files\Modules 子目录的特定于模块的子目录中安装该模块。

在以下示例中,Fabrikam 模块安装在 %ProgramFiles%\Common Files\Modules 子目录的 Fabrikam 子目录中。 请注意,每个模块驻留在 Modules 子目录中自己的子目录中。

C:\Program Files
  Common Files
    Modules
      Fabrikam
        Fabrikam.psd1 (module manifest)
        Fabrikam.dll (module assembly)

然后,安装程序确保 PSModulePath 环境变量的值包括 Common Files\Modules 子目录的路径。

$m = $Env:ProgramFiles + '\Common Files\Modules'
$p = [Environment]::GetEnvironmentVariable("PSModulePath")
$q = $p -split ';'
if ($q -notcontains $m) {
    $q += ";$m"
}
$p = $q -join ';'
[Environment]::SetEnvironmentVariable("PSModulePath", $p)

安装模块的多个版本

若要安装同一模块的多个版本,请使用以下过程。

  1. 为每个模块版本创建一个目录。 在目录名称中包含版本号。
  2. 为每个模块版本创建模块清单。 在清单中的 ModuleVersion 键的值中,输入模块版本号。 将清单文件(.psd1)保存在模块的版本特定的目录中。
  3. 将模块根文件夹路径添加到 PSModulePath 环境变量的值,如以下示例所示。

若要导入模块的特定版本,最终用户可以使用 Import-Module cmdlet 的 MinimumVersionRequiredVersion 参数。

例如,如果 Fabrikam 模块在版本 8.0 和 9.0 中可用,Fabrikam 模块目录结构可能如下所示。

C:\Program Files
Fabrikam Manager
 Fabrikam8
   Fabrikam
     Fabrikam.psd1 (module manifest: ModuleVersion = "8.0")
     Fabrikam.dll (module assembly)
 Fabrikam9
   Fabrikam
     Fabrikam.psd1 (module manifest: ModuleVersion = "9.0")
     Fabrikam.dll (module assembly)

安装程序将这两个模块路径添加到 PSModulePath 环境变量值。

$p = [Environment]::GetEnvironmentVariable("PSModulePath")
$p += ";C:\Program Files\Fabrikam\Fabrikam8;C:\Program Files\Fabrikam\Fabrikam9"
[Environment]::SetEnvironmentVariable("PSModulePath",$p)

这些步骤完成后,Get-Module cmdlet 的 ListAvailable 参数获取两个 Fabrikam 模块。 若要导入特定模块,请使用 Import-Module cmdlet 的 MinimumVersionRequiredVersion 参数。

如果两个模块都导入到同一会话中,并且模块包含具有相同名称的 cmdlet,则最后导入的 cmdlet 在会话中有效。

处理命令名称冲突

当模块导出的命令与用户会话中的命令同名时,可能会发生命令名称冲突。

当会话包含两个具有相同名称的命令时,Windows PowerShell 将运行优先的命令类型。 当会话包含两个具有相同名称和相同类型的命令时,Windows PowerShell 将运行最近添加到会话中的命令。 若要运行默认未运行的命令,用户可以使用模块名称限定命令名称。

例如,如果会话包含 Get-Date 函数和 Get-Date cmdlet,则 Windows PowerShell 默认运行该函数。 若要运行 cmdlet,请在命令前面加上模块名称,例如:

Microsoft.PowerShell.Utility\Get-Date

为了防止名称冲突,模块作者可以使用模块清单中的 DefaultCommandPrefix 键来指定从模块导出的所有命令的名词前缀。

用户可以使用 Import-Module cmdlet 的 Prefix 参数来使用备用前缀。 Prefix 参数的值优先于 DefaultCommandPrefix 键的值。

支持非 Windows 系统上的路径

非 Windows 平台使用冒号(:)字符作为路径分隔符,将正斜杠(/)字符用作目录分隔符。 [System.IO.Path] 类具有静态成员,可用于使代码在任何平台上工作:

  • [System.IO.Path]::PathSeparator - 返回用于分隔主机平台的 PATH 环境变量中的路径的字符
  • [System.IO.Path]::DirectorySeparatorChar - 返回用于使用主机平台路径分隔目录名称的字符

在构造路径字符串时,使用这些静态属性代替 ;\ 字符。

另请参阅

关于命令优先级

编写 Windows PowerShell 模块