问题
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