【问题标题】:PowerShell manifest referencing external assembly引用外部程序集的 PowerShell 清单
【发布时间】:2011-01-08 09:28:01
【问题描述】:

是否可以通过定义一个新的模块清单并将其放入指定目录来注册一个新的PowerShell模块?

例如a 应该创建一个名为 SampleModule 的新模块。我将空清单文件SampleModule.psd1 放在目录<%PSModulePath%>\SampleModule 中。 (使用哪个(用户或全局)模块路径并不重要)。

这足以让 PowerShell 使用 Get-Module -ListAvailable 命令列出我的新模块。

在下一步中,我尝试填充清单并将ModuleToProcess 属性设置为位于另一个目录中的程序集。调用Import-Module 失败,PowerShell 找不到程序集。

【问题讨论】:

    标签: .net powershell powershell-2.0


    【解决方案1】:

    确实如此。事实上,我有一个非常漂亮的技巧可以为 SQL 管理单元执行此操作。代码的第一块是一个函数,它将从一个模块位置为您创建一个模块清单。它仍然会提示您(就像 New-ModuleManifest cmdlet 一样)一些必需的参数,例如描述。它会查找任何类型和格式文件,以及任何名为 .ps.dll 的 .dll(大多数管理单元都遵循此约定),然后它会创建一个包装原始模块的模块清单。第二段代码专门针对 SQL PSSnapin 执行此操作。

    function New-ModuleManifestFromSnapIn {
    
        [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Medium')]
        param(
    
        [Parameter(Mandatory=$true, Position=0)]
        [System.String]
        ${Path},
    
        # The location in the filesystem where the V1 snapin resides
        [Parameter(Mandatory=$true)]
        [System.String]
        ${OriginalPath},
    
        [System.Guid]
        ${Guid},
    
        [Parameter(Mandatory=$true)]
        [AllowEmptyString()]
        [System.String]
        ${Author},
    
        [Parameter(Mandatory=$true)]
        [AllowEmptyString()]
        [System.String]
        ${CompanyName},
    
        [Parameter(Mandatory=$true)]
        [AllowEmptyString()]
        [System.String]
        ${Copyright},
    
        [ValidateNotNull()]
        [System.Version]
        ${ModuleVersion},
    
        [Parameter(Mandatory=$true)]
        [AllowEmptyString()]
        [System.String]
        ${Description},
    
        [System.Reflection.ProcessorArchitecture]
        ${ProcessorArchitecture},
    
        [System.Version]
        ${PowerShellVersion},
    
        [System.Version]
        ${ClrVersion},
    
        [System.Version]
        ${DotNetFrameworkVersion},
    
        [System.String]
        ${PowerShellHostName},
    
        [System.Version]
        ${PowerShellHostVersion},
    
        [System.Object[]]
        ${RequiredModules},
    
        [AllowEmptyCollection()]
        [System.String[]]
        ${ScriptsToProcess},
    
        [AllowEmptyCollection()]
        [System.Object[]]
        ${ModuleList},
    
        [AllowNull()]
        [System.Object]
        ${PrivateData},
    
        [Switch]
        ${PassThru}
        )
    
        process {
            $types = Get-ChildItem $originalPath -Filter *.types.ps1xml
            $formats = Get-ChildItem $originalPath -Filter *.format.ps1xml
            $dlls = Get-ChildItem $originalPath -Filter *.ps*.dll
            $null = $psBoundParameters.Remove("OriginalPath")
            $psBoundParameters += @{
                VariablesToExport = "*"
                FunctionsToExport = "*"
                AliasesToExport = "*"
                CmdletsToExport = "*"
                FileList = @()
                RequiredAssemblies = @()
                ModuleToProcess = ""
                NestedModules = @($dlls | Select-Object -ExpandProperty FullName)
                TypesToProcess = @($types | Select-Object -ExpandProperty FullName)
                FormatsToProcess = @($formats | Select-Object -ExpandProperty FullName)
            }
            New-ModuleManifest @psBoundParameters
        }
    }
    

    此块将显示通过指向工具@SQL 创建清单。

    $basePath = $env:SqlSamplesSourceDataPath | Split-Path
    if (${env:ProgramFiles(x86)}) {
        $basePath = $basePath.Replace($env:ProgramFiles, ${env:ProgramFiles(x86)})
    } 
    
    $path = Join-Path $basePath "Binn"
    
    
    $basicMetaData = @{
        Author = "Microsoft Corporation"
        Description = "A Manifest to enable using the SQL PowerShell snapin in V2"
        CompanyName = "Microsoft Corporation"
        Copyright = (Get-Date).Year 
    }
    New-ModuleManifestFromSnapin -Path $psScriptRoot\Sql.psd1 -OriginalPath $path @BasicMetaData
    

    最后一个块会将所有名为当前区域性(即 SQL\en-us)的文件复制到模块目录中,这将使 Get-Help 对 cmdlet 起作用。

    这个技巧适用于一些管理单元,但可能需要对您想要作为模块重新公开的每个管理单元进行一些自定义。幸运的是,这是一次性成本。

    $Culture = Get-Culture
    $CultureList = "$path\$culture", 
        (Join-Path $path $culture.ThreeLetterIsoLanguageName), 
        (Join-Path $path $culture.TwoLetterIsoLanguageName)
    
    $CultureDirectory = Get-Item $CultureList -ErrorAction SilentlyContinue |
        Select-Object -First 1 
    
    if ($CultureDirectory) {
        $localDir = Join-Path $psScriptRoot (Split-Path $CultureDirectory -Leaf)
        $item = Get-Item $localDir -ErrorAction SilentlyContinue 
        if ($item) {
            Remove-Item $item -Recurse -Force 
        }
        Copy-Item $CultureDirectory $LocalDir -Recurse
    }
    

    希望对你有帮助

    【讨论】:

      【解决方案2】:

      带有-ListAvailable 参数的Get-Module cmdlet 效果很好。问题在于架构,即 32 位 PowerShell 主机无法列出 64 位模块...

      【讨论】:

        猜你喜欢
        • 2010-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-10
        • 1970-01-01
        • 1970-01-01
        • 2018-10-13
        相关资源
        最近更新 更多