【问题标题】:Accessing PrivateData during Import-Module在 Import-Module 期间访问 PrivateData
【发布时间】:2016-04-12 19:03:33
【问题描述】:

我想在我的模块加载时加载 config.xml 文件的内容并将其存储在 $PrivateData 中。这是我的 PSD1 中的定义行

# Private data to pass to the module specified in ModuleToProcess
PrivateData = @{'Variables'=@{};'Config'=$null}

这将创建一个包含两个项目的哈希表。 1) Variables 是我用来为我的模块存储私有变量的第二个哈希表。 2) Config 将包含 config.xml 文件的值。示例 XML:

<Config>
    <Foo>Bar</Foo>
</Config>

我可以使用以下行加载 xml:

$PrivateData  = $MyInvocation.MyCommand.Module.PrivateData
$PrivateData.Config = ([xml](Get-Content $PSScriptRoot\Config.xml | Out-String)).Config

我似乎无法在我的 PSM1 文件中访问它。我可以像这样将它包装在一个 Cmdlet 中:

Function Initialize-TestModule {
    $PrivateData  = $MyInvocation.MyCommand.Module.PrivateData
    $PrivateData.Config #= ([xml](Get-Content $PSScriptRoot\Config.xml | Out-String)).Config    
}

但随后用户必须拨打Import-Module 的电话,然后再拨打Initialize-TestModule 的第二次电话,这是我试图避免的。

如果我将代码放在 PSM1 中,当我调用 Import-Module 时会生成此错误

Property 'Config' cannot be found on this object; make sure it exists and is settable.
At C:\scripts\temp\TestModule\TestModule.psm1:7 char:2
+     $PrivateData.Config = ([xml](Get-Content $PSScriptRoot\Config.xml | Out-String) ...
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : PropertyNotFound

如果我尝试像这样加载 PSD1:

PrivateData = @{'Variables'=@{};'Config'=([xml](Get-Content $PSScriptRoot\Config.xml | Out-String)).Config}

我收到以下错误:

Import-Module : The module manifest 'C:\scripts\temp\TestModule\TestModule.psd1' could not be processed because it is
not a valid Windows PowerShell restricted language file. Please remove the elements that are not permitted by the
restricted language:
At C:\scripts\temp\TestModule\TestModule.psd1:88 char:26
+ PrivateData = @{'Config'=([xml](Get-Content $PSScriptRoot\Config.xml | Out-Strin ...
+                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Property references are not allowed in restricted language mode or a Data section.
At C:\scripts\temp\TestModule\TestModule.psd1:88 char:27
+ PrivateData = @{'Config'=([xml](Get-Content $PSScriptRoot\Config.xml | Out-Strin ...
+                           ~~~~~
The type xml is not allowed in restricted language mode or a Data section.
At C:\scripts\temp\TestModule\TestModule.psd1:88 char:33
+ PrivateData = @{'Config'=([xml](Get-Content $PSScriptRoot\Config.xml | Out-Strin ...
+                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The command 'Get-Content' is not allowed in restricted language mode or a Data section.
At C:\scripts\temp\TestModule\TestModule.psd1:88 char:72
+ PrivateData = @{'Config'=([xml](Get-Content $PSScriptRoot\Config.xml | Out-Strin ...
+                                                                        ~~~~~~~~~
The command 'Out-String' is not allowed in restricted language mode or a Data section.
At line:1 char:1
+ Import-Module .\TestModule -force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ResourceUnavailable: (C:\scripts\temp...TestModule.psd1:String) [Import-Module], Missing
   MemberException
    + FullyQualifiedErrorId : Modules_InvalidManifest,Microsoft.PowerShell.Commands.ImportModuleCommand

在我的 PSM1 中,我尝试使用 Invoke-CommandStart-Job 呼叫 Initialize-TestModule,但都失败了。那么有没有人在Import-Module 期间设法访问了 $PrivateData?

【问题讨论】:

  • $PrivateData.Config #= => # 是不是打错了,还是你真的有这个?
  • @mjolinor - 是的,这是一个错字。它不在我的代码中
  • 我相信PrivateData 应该用于写入 psd1 文件中的配置参数(因此可以在 psd1 中更改,即使对于签名模块也是如此)。如果您从单独的 xml 文件中读取配置,那么将其“放入”PrivateData 的原因是什么。您可以只放入一个名为 $Config 或类似名称的模块范围变量。然后,该模块内的所有函数都可以使用它。
  • psd1 中的代码是使用非常有限的 powershell 子集进行评估的。这是您面临的问题。而不是这种方法,您应该创建一个 ps1 文件,然后将其插入到 psd1 的 nestedmodules 部分中。这将在 import-module 时自动调用代码。

标签: powershell


【解决方案1】:

您可能需要使用 $MyInvocation 变量访问私有数据。但是,我只能通过从函数中调用它来使其工作。要将其加载到 PSM1 文件中的变量中,我从那里调用该函数。我是从https://social.technet.microsoft.com/Forums/windowsserver/en-US/9620af9a-0323-460c-b3e8-68a73715f99d/module-scoped-variable?forum=winserverpowershell 发现的。

function Get-PD
{
    [CmdletBinding()]
    Param()
    Begin{}
    Process
    {
        $MyInvocation.MyCommand.Module.PrivateData
    }
    End{}
}

$MyPD = Get-PD

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    相关资源
    最近更新 更多