Powershell 如何知道在哪里可以找到要导入的模块?
How does Powershell know where to find modules for import?
我真的处于使用命令行开关和 powershell 东西的初学者水平。我正在使用 PowerShell API 从 C# 调用命令行开关。我看到了奇怪的行为。在 stackoverfow 上的不同线程上,人们使用 Import-Command 或 PSImportModule 方法显式导入模块时,我可以查看 $env:PSModulePath 是否已经有可用的程序集,它会自动加载。此行为是默认情况下还是由于我忽略的标准配置。我正在运行在ms测试环境中进行单元测试。
我正在使用以下代码。
System.Management.Automation.PowerShell _powerShellInstance
_powerShellInstance.AddCommand("Connect-AzureRmAccount", false);
var output = _powerShellInstance.Invoke();
// Invoking my commandlets
_powerShellInstance.AddCommand("Get-LinkParameter", false);
以上命令自动从 C:\Windows\system32\WindowsPowerShellModules\v1.0\Modules\
加载程序集。我没有创建任何 运行space 也没有配置集。就在上面自动加载东西。我需要确认 powershell 和 运行 space 的行为究竟如何。因为我需要弄清楚我需要如何在生产机器上安装我的 commandlet。生产机器上的单元测试如何访问我的 commandlet 以完美加载。
虽然使用 Import-Module
显式加载您想要的模块是一种很好的做法,但由于 Powershell 3.0 如果模块在 $env:PSModulePath
返回的位置之一可用,它将自动加载默认情况下,如果它的一个 cmdlet 被调用。以下是不同路径的细分:
用户模块
$modulePath = "${env:UserProfile}\Documents\WindowsPowerShell\Modules"
此处安装的模块仅对当前用户的 Powershell 会话可用,默认情况下使用 Install-Module
安装的模块保存在此处。
所有用户模块
$modulePath = "${env:ProgramFiles}\WindowsPowerShell\Modules"
此处安装的模块可用于任何用户的 Powershell 会话。
系统模块
$modulePath = "${env:SystemRoot}\system32\WindowsPowerShell\v1.0\Modules"
此处安装的模块可在系统范围内用于任何 Powershell 会话,但应保持干净以便 Windows 进行管理。通常,您不想在这里安装自己的模块。
添加额外的模块路径
您可以向 $env:PSModulePath
添加其他路径,类似于修改 $env:PATH
变量以解析可执行路径的方式。它只是一个分号 ;
分隔的模块所在目录字符串,如果模块在 $env:PSModulePath
中的任何路径可用,Powershell 将知道在哪里可以找到它。事实上,您可能会看到其他已安装的工具可能已将自己的路径添加到 $env:PSModulePath
。执行此操作的 programs/toolsets 的一些示例是 Microsoft SQL Studio
、Microsoft System Center - Operations Manager
和 Chef Development Kit
.
导入不在路径上的模块
据我所知,您无法加载不属于 $env:PSModulePath
的 Powershell 模块。但是,您可以临时编辑 $env:PSModulePath
以包含包含您要加载的模块的目录。例如,如果您想从任意路径导入名为 TestModule
的模块:
$env:PSModulePath += ';C:\Path\To\Temporary\ModuleDirectory'
Import-Module TestModule
其中 TestModule
作为 C:\Path\To\Temporary\ModuleDirectory
的子文件夹存在
当您准备好结束您的 Powershell 会话时,您不需要撤销模块路径更改,因为上述更改是临时的。因此,您需要在每个会话中修改 $env:PSModulePath
,因此如果 TestModule
是您希望随时可用的内容,您可以将其复制到 [= 中的其他目录之一13=] 或永久添加 C:\Path\To\Temporary\ModuleDirectory
到 PSModulePath
环境变量。
关于 UNC 路径的注意事项
您还可以将 UNC(网络)路径添加到 $env:PSModulePath
。但是,我相信任何远程模块脚本仍将受制于系统上设置的 Powershell ExecutionPolicy
。
关于安装模块的更多信息
默认情况下,Install-Module
将模块安装到 User Modules 目录,但您可以使用 -Scope
参数稍微控制一下。例如,以下命令将更改模块的安装位置:
# Install to the current user location (default behavior if scope unspecified)
Install-Module -Scope CurrentUser $moduleName
# Install to the all users location (requires elevated permissions)
Install-Module -Scope AllUsers $moduleName
不幸的是,PowerShell 将帮助您将模块安装到这两个位置。系统模块对 PowerShell 的运行至关重要,不应由最终用户修改,添加到 $env:PSModulePath
的其他路径可能由 PowerShell 之外的软件管理,通常由 MSI 或其他安装程序管理。
此外,如果您编写的软件附带一个或多个 PowerShell 模块,最好让安装程序将新目录添加到系统 %PSModulePath%
并将模块放在那里,而不是安装到标准目录AllUsers 或 CurrentUser 路径,因为这些实际上是为了让最终用户随心所欲地进行管理。在这种情况下,让您的软件更新过程更新模块。这有利于防止意外修改或删除模块到不兼容的版本。
我真的处于使用命令行开关和 powershell 东西的初学者水平。我正在使用 PowerShell API 从 C# 调用命令行开关。我看到了奇怪的行为。在 stackoverfow 上的不同线程上,人们使用 Import-Command 或 PSImportModule 方法显式导入模块时,我可以查看 $env:PSModulePath 是否已经有可用的程序集,它会自动加载。此行为是默认情况下还是由于我忽略的标准配置。我正在运行在ms测试环境中进行单元测试。
我正在使用以下代码。
System.Management.Automation.PowerShell _powerShellInstance
_powerShellInstance.AddCommand("Connect-AzureRmAccount", false);
var output = _powerShellInstance.Invoke();
// Invoking my commandlets
_powerShellInstance.AddCommand("Get-LinkParameter", false);
以上命令自动从 C:\Windows\system32\WindowsPowerShellModules\v1.0\Modules\
加载程序集。我没有创建任何 运行space 也没有配置集。就在上面自动加载东西。我需要确认 powershell 和 运行 space 的行为究竟如何。因为我需要弄清楚我需要如何在生产机器上安装我的 commandlet。生产机器上的单元测试如何访问我的 commandlet 以完美加载。
虽然使用 Import-Module
显式加载您想要的模块是一种很好的做法,但由于 Powershell 3.0 如果模块在 $env:PSModulePath
返回的位置之一可用,它将自动加载默认情况下,如果它的一个 cmdlet 被调用。以下是不同路径的细分:
用户模块
$modulePath = "${env:UserProfile}\Documents\WindowsPowerShell\Modules"
此处安装的模块仅对当前用户的 Powershell 会话可用,默认情况下使用 Install-Module
安装的模块保存在此处。
所有用户模块
$modulePath = "${env:ProgramFiles}\WindowsPowerShell\Modules"
此处安装的模块可用于任何用户的 Powershell 会话。
系统模块
$modulePath = "${env:SystemRoot}\system32\WindowsPowerShell\v1.0\Modules"
此处安装的模块可在系统范围内用于任何 Powershell 会话,但应保持干净以便 Windows 进行管理。通常,您不想在这里安装自己的模块。
添加额外的模块路径
您可以向 $env:PSModulePath
添加其他路径,类似于修改 $env:PATH
变量以解析可执行路径的方式。它只是一个分号 ;
分隔的模块所在目录字符串,如果模块在 $env:PSModulePath
中的任何路径可用,Powershell 将知道在哪里可以找到它。事实上,您可能会看到其他已安装的工具可能已将自己的路径添加到 $env:PSModulePath
。执行此操作的 programs/toolsets 的一些示例是 Microsoft SQL Studio
、Microsoft System Center - Operations Manager
和 Chef Development Kit
.
导入不在路径上的模块
据我所知,您无法加载不属于 $env:PSModulePath
的 Powershell 模块。但是,您可以临时编辑 $env:PSModulePath
以包含包含您要加载的模块的目录。例如,如果您想从任意路径导入名为 TestModule
的模块:
$env:PSModulePath += ';C:\Path\To\Temporary\ModuleDirectory'
Import-Module TestModule
其中 TestModule
作为 C:\Path\To\Temporary\ModuleDirectory
当您准备好结束您的 Powershell 会话时,您不需要撤销模块路径更改,因为上述更改是临时的。因此,您需要在每个会话中修改 $env:PSModulePath
,因此如果 TestModule
是您希望随时可用的内容,您可以将其复制到 [= 中的其他目录之一13=] 或永久添加 C:\Path\To\Temporary\ModuleDirectory
到 PSModulePath
环境变量。
关于 UNC 路径的注意事项
您还可以将 UNC(网络)路径添加到 $env:PSModulePath
。但是,我相信任何远程模块脚本仍将受制于系统上设置的 Powershell ExecutionPolicy
。
关于安装模块的更多信息
默认情况下,Install-Module
将模块安装到 User Modules 目录,但您可以使用 -Scope
参数稍微控制一下。例如,以下命令将更改模块的安装位置:
# Install to the current user location (default behavior if scope unspecified)
Install-Module -Scope CurrentUser $moduleName
# Install to the all users location (requires elevated permissions)
Install-Module -Scope AllUsers $moduleName
不幸的是,PowerShell 将帮助您将模块安装到这两个位置。系统模块对 PowerShell 的运行至关重要,不应由最终用户修改,添加到 $env:PSModulePath
的其他路径可能由 PowerShell 之外的软件管理,通常由 MSI 或其他安装程序管理。
此外,如果您编写的软件附带一个或多个 PowerShell 模块,最好让安装程序将新目录添加到系统 %PSModulePath%
并将模块放在那里,而不是安装到标准目录AllUsers 或 CurrentUser 路径,因为这些实际上是为了让最终用户随心所欲地进行管理。在这种情况下,让您的软件更新过程更新模块。这有利于防止意外修改或删除模块到不兼容的版本。