如何使 Install-Module 也安装任何必需的模块?

mar*_*ark 3 powershell module powershell-module

我正在研究一个依赖于 SqlServer 的 PS 模块。

这是模块清单文件:

@{
    ModuleVersion = "1.0.19103.11"
    GUID = "59bc8fa6-b480-4226-9bcc-ec243102f3cc"
    Author = "..."
    CompanyName = "..."
    Copyright = "..."
    Description = "..."
    RequiredModules = ""
    ScriptsToProcess = "vsts\config.ps1"
    NestedModules = @( ... )
    PrivateData = @{
        PSData = @{
            ExternalModuleDependencies = @(
                "SqlServer"
            )
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是我用来发布模块的命令:

if (Get-PSRepository $PSRepositoryName -ErrorAction SilentlyContinue)
{
    Unregister-PSRepository $PSRepositoryName
}
Register-PSRepository $PSRepositoryName `
    -SourceLocation $NuGetRepoUrl `
    -PublishLocation $NuGetRepoUrl `
    -InstallationPolicy Trusted `
    -PackageManagementProvider nuget

Publish-Module -Name $ModuleManifestFile -NuGetApiKey $NuGetApiKey -Repository $PSRepositoryName -Force
Run Code Online (Sandbox Code Playgroud)

问题是当我安装这个模块时,我收到以下警告:

WARNING: The externally managed, dependent module 'SqlServer' is not installed on this computer. To use the current module 'xyz.PS.Core', ensure that its dependent
module 'SqlServer' is installed.
Run Code Online (Sandbox Code Playgroud)

如何在没有任何警告的情况下安装此包时自动安装 SqlServer。

我尝试设置 RequiredModules属性,但是如果构建机器没有安装模块 SqlServer,那么首先无法发布模块。我可以在那里安装它,但是有没有更好的方法而不强迫我们在构建代理上安装软件包?

编辑 1

因此,我在构建代理上安装了 SqlServer 模块并添加了该RequiredModules属性。显示相同的警告。但现在我什至无法导入模块:

Import-Module : The required module 'SqlServer' is not loaded. Load the module or remove the module from 'RequiredModules' in the file
Run Code Online (Sandbox Code Playgroud)

编辑 2

我仍然无法使它工作。让我展示所有的组合。在所有情况下,测试机器上都没有安装 SqlServer 模块。

尝试 1

RequiredModules = @(
    @{
        ModuleName = "SqlServer"
        ModuleVersion = "21.1.18068"
    }
)
PrivateData = @{
    PSData = @{
        ExternalModuleDependencies = "SqlServer"
    }
}
Run Code Online (Sandbox Code Playgroud)

产量

C:\> Publish-Module -Name $ModuleManifestFile -NuGetApiKey $NuGetApiKey -Repository $PSRepositoryName -Force
PowerShellGet cannot resolve the module dependency 'SqlServer' of the module 'xyz.PS.Core' on the repository 'xyz-QA'. Verify that the dependent module 'SqlServer' is available in the repository 'xyz-QA'. If this dependent module 'SqlServer' is managed externally, add it to the ExternalModuleDependencies entry in the PSData section of the module manifest.
At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModule.psm1:1227 char:17
+                 Publish-PSArtifactUtility -PSModuleInfo $moduleInfo `
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Publish-PSArtifactUtility], InvalidOperationException
    + FullyQualifiedErrorId : UnableToResolveModuleDependency,Publish-PSArtifactUtility
C:\>
Run Code Online (Sandbox Code Playgroud)

尝试 2

RequiredModules = @("SqlServer")
PrivateData = @{
    PSData = @{
        ExternalModuleDependencies = "SqlServer"
    }
}
Run Code Online (Sandbox Code Playgroud)

产量

C:\> Publish-Module -Name $ModuleManifestFile -NuGetApiKey $NuGetApiKey -Repository $PSRepositoryName -Force
PowerShellGet cannot resolve the module dependency 'SqlServer' of the module 'xyz.PS.Core' on the repository 'xyz-QA'. Verify that the dependent module 'SqlServer' is available in the repository 'xyz-QA'. If this dependent module 'SqlServer' is managed externally, add it to the ExternalModuleDependencies entry in the PSData section of the module manifest.
At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModule.psm1:1227 char:17
+                 Publish-PSArtifactUtility -PSModuleInfo $moduleInfo `
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Publish-PSArtifactUtility], InvalidOperationException
    + FullyQualifiedErrorId : UnableToResolveModuleDependency,Publish-PSArtifactUtility
C:\>
Run Code Online (Sandbox Code Playgroud)

尝试 3

PrivateData = @{
    PSData = @{
        ExternalModuleDependencies = "SqlServer"
    }
}
Run Code Online (Sandbox Code Playgroud)

(否RequiredModules)产量:

C:\> Publish-Module -Name $ModuleManifestFile -NuGetApiKey $NuGetApiKey -Repository $PSRepositoryName -Force
C:\> Get-Module SqlServer -ListAvailable
C:\> Install-Module xyz.PS.Core -Scope CurrentUser -Force -AllowClobber
WARNING: The externally managed, dependent module 'SqlServer' is not installed on this computer. To use the current module 'xyz.PS.Core', ensure that its dependent module 'SqlServer' is installed.
C:\> Get-Module SqlServer -ListAvailable
C:\>
Run Code Online (Sandbox Code Playgroud)

如您所见,发布成功,但安装模块会输出警告。并且没有安装SqlServer。

尝试 4

RequiredModules = @(
    @{
        ModuleName = "SqlServer"
        ModuleVersion = "21.1.18068"
    }
)
Run Code Online (Sandbox Code Playgroud)

(没有 ExternalModuleDependencies)产量:

C:\> Publish-Module -Name $ModuleManifestFile -NuGetApiKey $NuGetApiKey -Repository $PSRepositoryName -Force
The specified RequiredModules entry 'SqlServer' in the module manifest 'C:\Users\mkharitonov\AppData\Local\Temp\2144858157\xyz.PS.Core\xyz.PS.Core.psd1' is invalid. Try again after updating this entry with valid values.At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModule.psm1:1144 char:27+ ... oduleInfo = Microsoft.PowerShell.Core\Test-ModuleManifest -Path $mani ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\Users\mkhari...ce.PS.Core.psd1:String) [Test-ModuleManifest], DirectoryNotFoundException
    + FullyQualifiedErrorId : Modules_InvalidRequiredModulesinModuleManifest,Microsoft.PowerShell.Commands.TestModuleManifestCommand
C:\>
Run Code Online (Sandbox Code Playgroud)

尝试 5

RequiredModules = @("SqlServer")
Run Code Online (Sandbox Code Playgroud)

(没有 ExternalModuleDependencies)产量:

C:\> Publish-Module -Name $ModuleManifestFile -NuGetApiKey $NuGetApiKey -Repository $PSRepositoryName -Force
The specified RequiredModules entry 'SqlServer' in the module manifest 'C:\Users\mkharitonov\AppData\Local\Temp\1208648280\xyz.PS.Core\xyz.PS.Core.psd1' is invalid. Try again after updating this entry with valid values.At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModule.psm1:1144 char:27+ ... oduleInfo = Microsoft.PowerShell.Core\Test-ModuleManifest -Path $mani ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\Users\mkhari...ce.PS.Core.psd1:String) [Test-ModuleManifest], DirectoryNotFoundException
    + FullyQualifiedErrorId : Modules_InvalidRequiredModulesinModuleManifest,Microsoft.PowerShell.Commands.TestModuleManifestCommand
C:\>
Run Code Online (Sandbox Code Playgroud)

所以,我所做的一切都不起作用。到目前为止,Powershell 似乎无法安装所需的模块。

我究竟做错了什么?

编辑 3

即使我在构建机器上安装了 SqlServer,RequiredModules 属性也不起作用。观察:

RequiredModules = @(
    "SqlServer"
)
PrivateData = @{
    PSData = @{
        ExternalModuleDependencies = "SqlServer"
    }
}
Run Code Online (Sandbox Code Playgroud)

结果是:

C:\> Get-Module SqlServer -ListAvailable


    Directory: C:\Users\mkharitonov\Documents\WindowsPowerShell\Modules


ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Script     21.1.18102 SqlServer                           {Add-RoleMember, Add-SqlAvailabilityDatabase, Add-SqlAvailabilityGroupListenerStaticIp, Ad...


C:\> Publish-Module -Name $ModuleManifestFile -NuGetApiKey $NuGetApiKey -Repository $PSRepositoryName -Force
PowerShellGet cannot resolve the module dependency 'SqlServer' of the module 'xyz.PS.Core' on the repository 'xyz-QA'. Verify that the dependent module 'SqlServer' is available in the repository 'xyz-QA'. If this dependent module 'SqlServer' is managed externally, add it to the ExternalModuleDependencies entry in the PSData section of the module manifest.
At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModule.psm1:1227 char:17
+                 Publish-PSArtifactUtility -PSModuleInfo $moduleInfo `
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Publish-PSArtifactUtility], InvalidOperationException
    + FullyQualifiedErrorId : UnableToResolveModuleDependency,Publish-PSArtifactUtility
C:\>
Run Code Online (Sandbox Code Playgroud)

Powershell 似乎在我的存储库中而不是在 PSGallery 中查找 SqlServer 模块。我不明白的方式。以下是机器上注册的 PS 存储库:

C:\> Get-PSRepository

Name                      InstallationPolicy   SourceLocation
----                      ------------------   --------------
PSGallery                 Trusted              https://www.powershellgallery.com/api/v2
xyz-QA                    Trusted             http://devstatic.xyz.com/nugetserver/nuget


C:\>
Run Code Online (Sandbox Code Playgroud)

所以,我真的不明白我应该做什么?

mkl*_*nt0 8

注意:以下内容是从PackageManagement (OneGet) GitHub repo 中的此讨论中收集的,特别是来自团队成员的评论

Install-Module适用于同一 repo 中的依赖项。
对于依赖模块托管在与要安装的模块不同的存储库中,我建议您将它们发布到您的内部存储库。
如果您不想将它们发布到您的内部存储库中,您可以将模块保存到您的公共文件共享,Register-PSRepository -Name local -SourceLocation \server\commonshare,然后首先从文件共享安装这些模块。”

PackageManagement 模块1.3 版开始,我根据您的症状得出结论,即使评论来自 2017 年年中(我找不到任何官方文档),上述内容仍然适用。

总结一下:

  • 不支持自动安装跨存储库依赖项;该解决方法是对外正式公布的依赖关系到您的内部回购以及

  • 在调用时Publish-Module条目中列出的模块RequiredModules似乎必须存在于同一个目标 repo 中

    • 也就是说,这些模块单独机器上的存在是足够的。(我不清楚他们是否需要在场——他们不应该必须在场。)
  • 为了支持内部存储库依赖PrivateData.PSData.ExternalModuleDependencies项的自动安装,条目还必须列出这些依赖项- 除了RequiredModules-仅按名称- 见下文。

为自动依赖安装指定内部存储库模块依赖(未验证)

# Specify what other modules this module requires to work, using a FQMN,
# (a Fully Qualified Module Name), via a hashtable.
# The 'ModuleVersion' entry version numbers specifies a *minimum* required version 
# number; 'RequiredVersion' specifies an *exact* version, and  
# 'MaximumVersion' specifies a maximum version.
# IMPORTANT:
#   If you publish a module whose manifest has a 'RequiredModules'
#   entry to a repository with Publish-Module, all referenced modules
#   seemingly *must exist in that repository.*
RequiredModules = @( @{ModuleName = 'SqlServer'; ModuleVersion = '21.1.18068' } )


PrivateData = @{
  PSData = @{

    # ... 

    # !! This field is *ancillary* to the more detailed 'RequiredModules' field and
    # !! must reference the *same modules*, but by *names only*,
    # !! in order to automatically install other modules
    # !! *from the same repository* that this module depends on.
    # !! To be safe, specify even a *single* name as an *array*
    # !! (While this is not a general requirement in manifests, 
    # !!  it may be necessary here due to a bug.)
    ExternalModuleDependencies = @('SqlServer')
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句:New-ModuleManifest当前的一个错误阻止了直接创建PrivateData.PSData.ExternalModuleDependencies条目:

# !! BROKEN as of Windows PowerShell v5.1 / PowerShell Core 6.2.0;
# The inner hashtable ends up represented as 'System.Collections.Hashtable'
New-ModuleManifest someManifest.psd1 -PrivateData @{ 
  PSData = @{
    ExternalModuleDependencies = @('SqlServer')
  }
}
Run Code Online (Sandbox Code Playgroud)

请参阅此 GitHub 问题