3

下面的这个模块返回一个空对象。有什么建议可以解决吗?

New-Module -ScriptBlock { 
    $resourcesDirectory="AA"
    .....
    $commonProperties = New-Object PSObject -Property @{
        ResourcesDirectory = $resourcesDirectory
    }

    return $commonProperties 
} -name GetXXX
4

1 回答 1

1

PetSerAl 致敬以寻求帮助。

New-Module默认情况下返回新创建的模块,作为一个[System.Management.Automation.PSModuleInfo]实例。

通过“返回一个空对象”,我假设您的意思是让您的模块导出变量$commonProperties 它恰好包含一个[pscustomobject]实例,但这是偶然的),但您的代码未能这样做。

原因是在没有Export-ModuleMember调用的情况下,变量别名(与函数不同)不会自动从模块中导出

注意事项

  • 如果存在一个或多个Export-ModuleMember调用,导出指定的成员(不会自动导出任何内容)。

  • Export-ModuleMember调用最好放在模块定义的底部,因为它们必须元素定义之后才能导出。

  • 如果要将导入当前会话的导出成员限制为模块功能的子集,可以使用New-Module's-Function参数。

    • 如果该模块仅在当前会话中使用,则New-Module -FunctionExport-ModuleMember;结合没有意义。还要注意 using-Function会阻止非函数成员被导入当前会话。
    • 结合默认的导出行为,New-Module -Function 有效地提供了一种Export-ModuleMember在脚本块内使用带有函数名称的显式调用的替代方法,但重要的是要了解这两种机制的不同。

要导出变量$commonProperties,您需要调用Export-ModuleMember -Variable commonProperties$(注意变量名中需要缺少前缀):

$newModule = New-Module -ScriptBlock { 
    $resourcesDirectory="AA"
    $commonProperties = New-Object PSObject -Property @{
        ResourcesDirectory = $resourcesDirectory
    }

    # You must explicitly export variable $commonProperties.
    # Note that `Export-ModuleMember` must generally come *after* the 
    # definition of the variable, and that the variable name 
    # must not be $-prefixed.
    Export-ModuleMember -Variable commonProperties

    # (No need to `return` anything from the script block.
    #  Any output will be ignored.)
} -name GetXXX

鉴于New-Module不仅创建了一个新模块而且自动导入它,$commonProperties现在在当前会话中可用。


旁注

通过添加 switch ,-ReturnResult可以告诉New-Module返回脚本块的输出而不是新创建的模块对象(但模块仍然导入到当前会话中)。

由于该语句,应用于将返回variable的代码,但如前所述,您的脚本块不会导出任何成员,因此当前会话不会看到variable$commonPropertiesreturn $commonProperties$commonProperties


或者, switch-AsCustomObject告诉New-Module返回一个[pscustomobject]实例,其成员是导出的成员
请注意,正常的导出规则适用,并且模块仍在幕后创建,尽管它没有导入

应用于您的(更正的)代码,并Foo添加了导出功能:

$newObj = New-Module -ScriptBlock { 
    $resourcesDirectory="AA"
    $commonProperties = New-Object PSObject -Property @{
        ResourcesDirectory = $resourcesDirectory
    }
    function Foo { "I'm here." }
    Export-ModuleMember -Variable commonProperties -Function Foo
} -AsCustomObject

$newObj现在包含一个名为的属性,该属性commonProperties引用$commonProperty来自新(隐藏)模块的脚本块的变量。

注意:Get-Member误导性地将此属性的类型报告为NoteProperty,暗示一个静态值,而导出的函数可能会改变基础变量的值(尽管这让我觉得很奇怪)。[System.Management.Automation.PSVariableProperty]正如所$newObj.psobject.properties['commonProperties'].GetType().FullName揭示的那样,真正的类型是,而真正的NoteProperty成员具有 type [System.Management.Automation.PSNoteProperty]

类似地,导出的函数 Foo表面为ScriptMethod-type 成员(方法),在新(隐藏)模块的上下文中运行并查看变量。
(顺便说一句:$newObj.Foo.Script.Module可用于访问隐藏模块。)

相比之下,导出的别名似乎被忽略了。

警告:不要以相同的名称导出不同类型的成员(例如,不要定义同名的函数和变量),因为只有其中一个可以访问。

于 2016-06-23T01:46:19.580 回答