How does Powershell know where to find modules for import?

末鹿安然 提交于 2020-12-30 02:34:05

问题


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.

I am using following code.

 System.Management.Automation.PowerShell _powerShellInstance
 _powerShellInstance.AddCommand("Connect-AzureRmAccount", false);
 var output = _powerShellInstance.Invoke();

 // Invoking my commandlets

 _powerShellInstance.AddCommand("Get-LinkParameter", false); 

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.


回答1:


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:

User Modules

$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.

All User Modules

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

System Modules

$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.

Adding Additional Module Paths

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.

Importing a Module Not On the Path

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

where TestModule exists as a direct sub-folder of C:\Path\To\Temporary\ModuleDirectory

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.

A Note About UNC Paths

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.



来源:https://stackoverflow.com/questions/51207167/how-does-powershell-know-where-to-find-modules-for-import

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!