如何将模块安装到自定义目录?

14

目前我们正在使用以下命令安装某些模块,但它会将模块安装在 C:\Program Files\WindowsPowerShell\Modules 中。

Install-Module -Name XXX -RequiredVersion XXX -Repository XXX -Scope AllUsers
我们的要求是将此模块安装在 E:\Modules 文件夹中。为此,我更新了 PSModulePath 环境变量如下。(https://msdn.microsoft.com/en-us/library/dd878350(v=vs.85).aspx
$p = [Environment]::GetEnvironmentVariable("PSModulePath")
$p += ";E:\Modules"
[Environment]::SetEnvironmentVariable("PSModulePath",$p)

但是它仍然安装在C:\Program Files\WindowsPowerShell\Modules

在安装模块之前,如何将PSModulePath更新为E:\Modules


我目前也在与此搏斗,但至今尚未找到一个真正好的解决方案。你找到解决方案了吗? - Lieven Keersmaekers
3个回答

19
您可以使用Save-Module命令手动下载模块zip。
Find-Module -Name 'XXX' -Repository 'PSGallery' | Save-Module -Path 'E:\Modules'

从这里开始,你可以使用完全合格的名称导入模块,像这样:

从这里开始,您可以使用完全合格的名称导入模块,如下所示:

Import-Module -FullyQualifiedName 'E:\Modules\XXX'

或者像之前一样,将目标文件夹添加到PSModulePath中。

$modulePath = [Environment]::GetEnvironmentVariable('PSModulePath')
$modulePath += ';E:\Modules'
[Environment]::SetEnvironmentVariable('PSModulePath', $modulePath)

您随后可以使用 Get-Module 命令来检查模块是否已导入。


如果您正在使用Import-Module 命令,这可能会有些麻烦,特别是如果您有很多模块。因此,您可以将此方法封装在函数中,如下所示:

function Install-ModuleToDirectory {
    [CmdletBinding()]
    [OutputType('System.Management.Automation.PSModuleInfo')]
    param(
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        $Name,

        [Parameter(Mandatory = $true)]
        [ValidateScript({ Test-Path $_ })]
        [ValidateNotNullOrEmpty()]
        $Destination
    )

    # Is the module already installed?
    if (-not (Test-Path (Join-Path $Destination $Name))) {
        # Install the module to the custom destination.
        Find-Module -Name $Name -Repository 'PSGallery' | Save-Module -Path $Destination
    }

    # Import the module from the custom directory.
    Import-Module -FullyQualifiedName (Join-Path $Destination $Name)

    return (Get-Module)
}

Install-ModuleToDirectory -Name 'XXX' -Destination 'E:\Modules'

1
为了控制模块安装路径,您需要停止使用 -Scope 标志。如果您不指定作用域,则默认安装位置是从 $env:PSModulePath 环境变量返回的第一个路径。如果您直接在脚本中修改此变量,它仅会持续存在于您的会话中。这可能是您正在做的理想情况。
首先,在变量中添加自定义路径作为第一项:
$env:PSModulePath = "E:\Modules;" + $env:PSModulePath

然后当您运行安装时,它将使用该路径:

Install-Module -Name XXX -RequiredVersion XXX -Repository XXX

您可以选择将该设置永久保存:

[Environment]::SetEnvironmentVariable("PSModulePath", $env:PSModulePath)

Microsoft Doc 中所述。

1
我使用上述命令将自定义路径设置为PSModulePath的第一个条目。但是,Install-Module仍然安装在默认的C:/Program Files/...路径下。因此,它不仅跳过了我的自定义路径,还跳过了我的默认用户模块路径。 - Blaisem
通过使用 Write-Output 查看 $env:PSModulePath 的内容。第一个列出的路径是什么?它是安装位置吗? - HackSlash
1
列出的第一条路径是我的自定义路径。它安装到的路径是C:\Program Files\WindowsPowerShell\Modules。你自己试过了吗?也许是PS版本的问题?我的版本是PowerShell 5.1.14393。 - Blaisem
我已经尝试过了,PowerShell 的这个方面的确像文档中描述的那样运作。如果不是这样,那就是一个 bug。 - HackSlash
ftr - 对我也不起作用。将一个本地可写文件夹添加为PSModulePath中的第一个文件夹,并在使用Install-Module时不带范围参数,Install-Module会尝试安装到所有用户位置,这需要管理员权限。 - Lieven Keersmaekers
我不确定这是如何工作的,除非 Microsoft 进行了追溯更改文档。他们非常清楚地表明 PSGet 只安装到 $env:ProgramFiles\PowerShell\Modules 或 $HOME\Documents\PowerShell\Modules。https://learn.microsoft.com/en-us/powershell/module/powershellget/install-module - pl4nty

-1

$env:PSModulePath是一个环境变量,用于在执行Import-Module时搜索模块,并从PS V3开始进行模块自动加载。

如果您查看Install-Module的帮助文件,我无法看到提供模块安装路径的选项。

因此,作为解决方法,您可以基于模块名称(每个模块的文件夹名称相同)创建一个复制作业到您的自定义路径。

此致

Kvprasoon


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接