我真的是初学者,可以使用Commandlet和Powershell东西。我正在使用PowerShell API从C#调用Commandlet。我看到了奇怪的行为。当人们在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\
加载程序集。我还没有创建任何运行空间,也没有配置集。就在上面自动加载东西。我需要确认Powershell和运行空间的行为如何。因为我需要清除然后在生产机器上安装Commandlet的方式。在生产机器上进行单元测试的方式将访问我的Commandlet以完美加载。
答案 0 :(得分:1)
虽然最好的做法是使用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
。可以执行此操作的程序/工具集的一些示例是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
,可以将其复制到{{ 1}}或将$env:PSModulePath
永久添加到C:\Path\To\Temporary\ModuleDirectory
环境变量中。
您还可以将UNC(网络)路径添加到PSModulePath
。但是,我相信任何远程模块脚本仍将受系统上设置的Powershell $env:PSModulePath
的约束。