about_Modules

简短说明

介绍如何安装、导入和使用 PowerShell 模块。

长说明

PowerShell 既是命令行界面,也是脚本语言。 PowerShell 中的命令作为脚本、函数或 cmdlet 实现。 该语言包括 关键字,这些关键字提供处理的结构和逻辑,以及其他资源,例如变量、提供程序、别名。

模块是一个自包含的可重用单元,可以包含 cmdlet、提供程序、函数、变量和其他资源。 默认情况下,PowerShell 会在首次使用模块中的命令时自动加载已安装的模块。 可以使用变量 $PSModuleAutoloadingPreference配置自动模块加载行为。 有关详细信息,请参阅 about_Preference_Variables

也可以在 PowerShell 会话期间手动加载或卸载模块。 若要加载或重新加载模块,请使用 Import-Module。 若要卸载模块,请使用 Remove-Module cmdlet。

PowerShell 包含一组基本模块。 任何人都可以使用 C# 或 PowerShell 脚本语言本身创建新模块。 以 C# 编写为已编译的 .NET 程序集的模块称为本机模块。 在 PowerShell 中编写的模块称为脚本模块。

本文介绍如何使用 PowerShell 模块。 有关如何创建 PowerShell 模块的信息,请参阅 编写 PowerShell 模块

注意

在 PowerShell 3.0 之前,cmdlet 和提供程序打包在 PowerShell 管理单元中。从 PowerShell 3.0 开始,默认情况下, Microsoft.PowerShell.Core 管理单元添加到每个会话。 这是 PowerShell 中唯一的管理单元。 所有其他管理单元已转换为模块。 不再支持创建新的管理单元。

默认模块位置

PowerShell 将模块存储在以下默认位置:

  • 所有用户范围 - $env:ProgramFiles\WindowsPowerShell\Modules
  • 当前用户范围 - $HOME\Documents\WindowsPowerShell\Modules
  • PowerShell 随附的模块 - $PSHOME\Modules

默认情况下, Modules 当前用户的文件夹不存在。 如果使用或Install-PSResource这些 cmdlet 在作用域Install-ModuleCurrentUser安装了模块,则Modules这些 cmdlet 将为当前用户创建文件夹。 如果文件夹不存在,可以手动创建它。

使用以下命令为当前用户创建 Modules 文件夹:

$folder = New-Item -Type Directory -Path $HOME\Documents\WindowsPowerShell\Modules

这些位置自动包含在环境变量中 $env:PSModulePath 。 有关默认模块位置的详细信息,请参阅 about_PSModulePath

模块自动加载

首次从已安装的模块运行命令时,PowerShell 会自动导入该模块(加载)。 模块必须存储在环境变量中指定的 $env:PSModulePath 位置。

模块自动加载允许在模块中使用命令,而无需任何设置或配置文件配置。 以下示例中的每个示例都会导致 CimCmdlet 模块 (其中包含 Get-CimInstance)导入到会话中。

  • 运行命令

    Get-CimInstance Win32_OperatingSystem
    
  • 获取命令

    Get-Command Get-CimInstance
    
  • 获取命令的帮助

    Get-Help Get-CimInstance
    

Get-Command 通配符(*)一起使用时,PowerShell 不会导入任何模块。 可以将通配符用于命令发现,而无需加载会话中可能不需要的模块。

手动导入模块

当模块未安装在环境变量指定 $env:PSModulePath 的位置,或者当模块作为独立 .dll 模块或 .psm1 文件提供时,而不是打包的模块时,需要手动导入模块。

此外,使用 PowerShell 提供程序的命令不会自动导入模块。 例如,如果使用需要WSMan:驱动器(如 Get-PSSessionConfiguration cmdlet)的命令,则可能需要运行 Import-Module cmdlet 来导入包含WSMan:驱动器的 Microsoft.WSMan.Management 模块。

你可能还想要更改模块在会话中导入的方式。 例如, 用于向从模块导入的 cmdlet 的名词部分添加一个独特的前缀的 Prefix 参数 Import-ModuleNoClobber 参数阻止模块添加命令,这些命令将隐藏或替换会话中的现有命令。 有关详细信息,请参阅 “管理名称冲突”。

以下示例将 BitsTransfer 模块导入当前会话。

Import-Module BitsTransfer

若要导入不在你的 $env:PSModulePath模块中,请使用模块文件夹的完全限定路径。 例如,若要将目录中的 TestCmdlet 模块C:\ps-test添加到会话,请键入:

Import-Module C:\ps-test\TestCmdlets

若要导入模块文件夹中不包含的模块文件,请使用命令中模块文件的完全限定路径。 例如,若要将 C:\ps-test 目录中的 TestCmdlets.dll 模块添加到会话,请键入:

Import-Module C:\ps-test\TestCmdlets.dll

有关将模块添加到会话的详细信息,请参阅 Import-Module

在每个会话开始时导入模块

Import-Module 命令将模块导入到当前的 PowerShell 会话中。 若要将模块导入到启动的每个 PowerShell 会话中,请将 Import-Module 命令添加到 PowerShell 配置文件。

有关配置文件的详细信息,请参阅 about_Profiles

安装已发布的模块

已发布的模块是从已注册的存储库(如PowerShell 库)提供的模块。 PowerShellGetMicrosoft.PowerShell.PSResourceGet 模块提供用于查找、安装和将 PowerShell 模块发布到已注册存储库的 cmdlet。

PowerShellGet 模块包含在 PowerShell 5.0 及更高版本中。 Microsoft.PowerShell.PSResourceGet 模块包含在 PowerShell 7.4 及更高版本中,是 PowerShell 的首选包管理器。 Microsoft.PowerShell.PSResourceGet 可与旧版 PowerShell 上的 PowerShellGet 并排安装。 Install-Module使用或 Install-PSResource cmdlet 从PowerShell 库安装模块。

 Get-Command Install-Module, Install-PSResource
CommandType  Name                Version    Source
-----------  ----                -------    ------
Function     Install-Module      2.9.0      PowerShellGet
Cmdlet       Install-PSResource  1.0.0      Microsoft.PowerShell.PSResourceGet

有关详细信息,请参阅 PowerShellGet 概述

手动安装模块

可以通过从另一个文件夹中复制模块内容来手动安装模块。 该文件夹可以位于本地计算机上的另一个位置,也可以安装在另一台计算机上。 若要手动安装模块,请将整个模块文件夹复制到包含在你的 $env:PSModulePath新位置。

在 PowerShell 中使用 Copy-Item cmdlet。 例如,运行以下命令,从C:\PSTest中复制MyModule文件夹:

$modulePath = $HOME\Documents\PowerShell\Modules\MyModule
Copy-Item -Path C:\PSTest\MyModule\* -Destination $modulePath -Recurse

你可以在任何位置上安装模块,但在默认模块位置中安装模块可使其更易于管理。

查找已安装的模块

Get-Module cmdlet 获取当前 PowerShell 会话中加载的 PowerShell 模块。

Get-Module

列出的模块可以包括从任何位置导入的模块,而不仅仅是从 $env:PSModulePath任何位置导入的模块。

使用以下命令列出安装在以下项 $env:PSModulePath中的模块:

Get-Module -ListAvailable

此命令获取安装 $env:PSModulePath的所有模块,而不仅仅是导入到当前会话中的模块。 此命令不会列出在其他位置安装的模块。

有关详细信息,请参阅 Get-Module

列出模块中的命令

使用 Get-Command cmdlet 查找所有可用的命令。 可以使用 Get-Command cmdlet 的参数按模块、名称和名词等来筛选命令。

若要查找模块中的所有命令,请键入:

Get-Command -Module <module-name>

例如,若要在 BitsTransfer 模块中找到命令,请键入:

Get-Command -Module BitsTransfer

有关 Get-Command cmdlet 的详细信息,请参阅 Get-Command

删除模块

当你删除模块时,该模块所添加的命令将从会话中删除。 例如,以下命令从 当前会话中删除 BitsTransfer 模块。

Remove-Module BitsTransfer

删除模块与导入模块的操作相反。 删除模块不会卸载该模块。 有关详细信息,请参阅 Remove-Module

可以从模块和管理单元将命令添加到会话。模块可以添加所有类型的命令,包括 cmdlet、提供程序和函数,以及变量、别名和 PowerShell 驱动器等项。 管理单元只可以添加 cmdlet 和提供程序。

在从会话中删除模块之前,请使用以下命令确定要删除的模块。

例如,使用以下命令查找和 Get-Help cmdlet 的Get-Date源:

Get-Command Get-Date, Get-Help -All |
    Select-Object -Property Name, CommandType, Module ,PSSnapIn

以下输出显示 Get-Help cmdlet 位于 Microsoft.PowerShell.Core 管理单元中。 无法从会话中删除此管理单元。

Name     CommandType Module                       PSSnapIn
----     ----------- ------                       --------
Get-Date    Function
Get-Date      Cmdlet Microsoft.PowerShell.Utility
Get-Help      Cmdlet                              Microsoft.PowerShell.Core

有两个来源 Get-Date。 一个是函数,另一个是 Microsoft.PowerShell.Utility 模块中的 cmdlet。 可以使用 Remove-Module.. 若要删除函数,可以从驱动器中删除它 Function:

Remove-Item Function:Get-Date

有关驱动器的详细信息 Function: ,请参阅 about_Function_Provider

管理名称冲突

当会话中的多个命令具有相同的名称时,会发生名称冲突。 当模块中的命令与会话中的命令或项具有相同名称时,导入模块将引起名称冲突。

Import-Module 可能会添加命令来隐藏和替换当前会话中的命令。 名称冲突可能会导致命令被隐藏或替换。 当导入的模块包含与会话中的现有命令同名的命令时,会发生命令替换。 新导入的命令优先于现有命令。

例如,当会话中包含具有相同名称的一个函数和一个 cmdlet 时,PowerShell 在默认情况下会运行该函数。 当会话中包含同一类型的同名命令时(例如具有相同名称的两个 cmdlet),它将在默认情况下运行最新添加的命令。

有关详细信息,包括优先规则的说明和运行隐藏命令的说明,请参阅 about_Command_Precedence

可以通过限定命令名称来运行隐藏或替换的命令。 若要限定命令名称,请添加包含所需命令版本的模块的名称。 例如:

Microsoft.PowerShell.Utility\Get-Date

使用模块名称前缀运行 Get-Date 可确保从 Microsoft.PowerShell.Utility 模块运行版本。

若要检测名称冲突,请使用 Get-Command cmdlet 的 All 参数。 默认情况下, Get-Command 仅获取键入命令名称时运行的命令。 All 参数获取会话中具有特定名称的所有命令。

若要防止名称冲突,请使用 Import-Module cmdlet 的 NoClobberPrefix 参数。 Prefix 参数将前缀添加到导入的命令的名称,以便它们在会话中是唯一的。 NoClobber 参数不会导入任何命令,这些命令将隐藏或替换会话中的现有命令。

还可以使用 Import-ModuleAliasCmdletFunctionVariable 参数来仅选择要导入的命令,并且可以排除在会话中引起名称冲突的命令。

模块作者可以通过使用模块清单的 DefaultCommandPrefix 属性来将默认前缀添加到所有命令名称,从而避免名称冲突。 Prefix 参数的值优先于 DefaultCommandPrefix 的值。

另请参阅