Powershell 如何知道在哪里可以找到要导入的模块? [英] How does Powershell know where to find modules for import?

查看:53
本文介绍了Powershell 如何知道在哪里可以找到要导入的模块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于使用命令行开关和 powershell 东西,我真的处于初学者级别.我正在使用 PowerShell API 从 C# 调用命令行开关.我看到了奇怪的行为.虽然在 stackoverfow 的不同线程上,人们使用 Import-Command 或 PSImportModule 方法显式导入模块,但我可以查看 $env:PSModulePath 中是否有可用的程序集,它会自动加载.这种行为是默认情况下还是由于我忽略的标准配置.我在 ms 测试环境中运行单元测试.

I am really at beginner level for working with commandlets and powershell stuff. I am invoking commandlets from C# using PowerShell API. I saw strange behaviours. While on different threads on stackoverfow, people explicitly importing modules using Import-Command or PSImportModule method, I can see if there is an assembly at $env:PSModulePath available already, it is automatically loaded. Does this behaviour is by default or due to criteria configurations which i m overlooking. I am running unit test in ms test environment.

我正在使用以下代码.

 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\ 加载程序集.我没有创建任何运行空间,也没有配置集.就在上面自动加载东西.我需要确认 powershell 和运行空间的行为究竟如何.因为我需要清楚我需要如何在生产机器上安装我的命令行开关.生产机器上的单元测试如何访问我的命令行开关以完美加载.

The above command automatically loads the assembly from C:\Windows\system32\WindowsPowerShellModules\v1.0\Modules\. I have not created any runspace and no configuration sets. Just above automatically loading things. I need to confirm how exactly is the powershell and run space behaves. Because I need to clear how i need to install my commandlets on production machine then. How unit tests on production machine will access my commandlets to perfectly get loaded.

推荐答案

虽然使用 Import-Module 显式加载您想要的模块是一种很好的做法,因为 Powershell 3.0 如果模块在$env:PSModulePath 返回的位置之一,如果调用其 cmdlet 之一,它将默认自动加载.以下是不同路径的细分:

While it is good practice to explicitly load the modules you want using Import-Module, since Powershell 3.0 if a module is available at one of the locations returned by $env:PSModulePath, it will automatically get loaded by default if one of its cmdlets are invoked. Below is a breakdown of the different paths:

$modulePath = "${env:UserProfile}\Documents\WindowsPowerShell\Modules"此处安装的模块仅对当前用户的 Powershell 会话可用,默认情况下使用 Install-Module 安装的模块保存在此处.

$modulePath = "${env:UserProfile}\Documents\WindowsPowerShell\Modules" Modules installed here are only available to the current user's Powershell session, and by default modules installed using Install-Module are saved here.

$modulePath = "${env:ProgramFiles}\WindowsPowerShell\Modules"此处安装的模块可供任何用户的 Powershell 会话使用.

$modulePath = "${env:ProgramFiles}\WindowsPowerShell\Modules" Modules installed here are available to any users' Powershell session.

$modulePath = "${env:SystemRoot}\system32\WindowsPowerShell\v1.0\Modules"此处安装的模块在系统范围内可用于任何 Powershell 会话,但应保持干净以供 Windows 管理.通常,您不想在此处安装自己的模块.

$modulePath = "${env:SystemRoot}\system32\WindowsPowerShell\v1.0\Modules" Modules installed here are available system wide to any Powershell session, but should be kept clean for Windows to manage. Typically, you do not want to install your own modules here.

您可以向 $env:PSModulePath 添加其他路径,这与修改 $env:PATH 变量以解析可执行路径的方式类似.它只是一个以分号 ; 分隔的模块所在目录字符串,如果模块在 $env:PSModulePath 中的任何路径可用,Powershell 将知道在哪里找到它.实际上,您可能会看到其他已安装的工具可能已将自己的路径添加到 $env:PSModulePath.执行此操作的程序/工具集的一些示例是 Microsoft SQL StudioMicrosoft System Center - Operations ManagerChef Development Kit.

You can add additional paths to $env:PSModulePath similarly to how you would modify the $env:PATH variable for resolving executable paths. It is simply a semicolon ; delimited string of directories where modules reside, and if a module is available at any path in $env:PSModulePath, Powershell will know where to find it. And in fact, you may see that other installed tools may have added their own paths to $env:PSModulePath. A few of examples of programs/toolsets which do this are Microsoft SQL Studio, Microsoft System Center - Operations Manager, and the Chef Development Kit.

据我所知,您不能加载不属于 $env:PSModulePath 的 Powershell 模块.但是,您可以临时编辑 $env:PSModulePath 以包含您要加载的模块的目录.例如,如果您想从某个任意路径导入名为 TestModule 的模块:

As far as I know, you cannot load a Powershell module that is not a part of $env:PSModulePath. However, you can temporarily edit $env:PSModulePath to contain a directory with a module you want to load. For example, if you wanted to import a module named TestModule from some arbitrary path:

$env:PSModulePath += ';C:\Path\To\Temporary\ModuleDirectory'
Import-Module TestModule

其中 TestModule 作为 C:\Path\To\Temporary\ModuleDirectory

当您准备好结束 Powershell 会话时,您无需取消模块路径更改,因为上述更改是暂时的.因此,您需要在每个会话中修改 $env:PSModulePath,所以如果 TestModule 是您希望始终可用的东西,您可以复制它到 $env:PSModulePath 中的其他目录之一或将 C:\Path\To\Temporary\ModuleDirectory 永久添加到 PSModulePath 环境变量.

You do not need to back out the module path change when you are ready to end your Powershell session as the change above is temporary. Consequently, you would need to modify $env:PSModulePath in every session, so if TestModule was something you wanted to have available at all times for use, you can either copy it to one of the other directories in $env:PSModulePath or permanently add C:\Path\To\Temporary\ModuleDirectory to the PSModulePath environment variable.

您还可以将 UNC(网络)路径添加到 $env:PSModulePath.但是,我相信任何远程模块脚本仍将受系统上设置的 Powershell ExecutionPolicy 约束.

You can also add UNC (network) paths to $env:PSModulePath. However, I believe any remote module scripts will still be subject to the Powershell ExecutionPolicy set on the system.

默认情况下,Install-Module 将模块安装到 User Modules 目录,但您可以使用 -Scope 稍微控制一下范围.例如,以下命令将更改模块的安装位置:

By default, Install-Module installs a module to the User Modules directory, but you can control this a bit with the -Scope parameter. For example, the following commands will change the location a module is installed into:

# 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 将帮助您安装模块的仅有的两个位置.System 模块对于 PowerShell 的操作至关重要,不应由最终用户修改,添加到 $env:PSModulePath 的其他路径可能由 PowerShell 之外的软件管理,通常由 MSI 或其他安装程序管理.

Unfortunately, those are the only two locations PowerShell will assist you installing your modules to. The System modules are critical to the operation of PowerShell and should not be modified by end users, and additional paths added to $env:PSModulePath are likely managed by software outside of PowerShell, typically by MSIs or other installers.

此外,如果您编写的软件附带一个或多个 PowerShell 模块,最好让安装程序将新目录添加到系统的 %PSModulePath% 并将模块放在那里,而不是安装到标准的 AllUsers 或 CurrentUser 路径,因为这些实际上是供最终用户随意管理的.在这种情况下,让您的软件更新过程更新模块.这有利于防止意外修改或将模块移除到不兼容的版本.

Additionally, if you write software that ships with one or more PowerShell modules it's good practice to have your installer add a new directory to the system's %PSModulePath% and drop the module there, rather than installing to the standard AllUsers or CurrentUser path, as these are really meant for the end user to manage at their whim. Have your software update process update the module in this case. This has the benefit of preventing accidental modification or removal of the module to an incompatible version.

这篇关于Powershell 如何知道在哪里可以找到要导入的模块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆