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ためです。

警告:

  • 1 つ以上のExport-ModuleMember呼び出し存在する場合、指定されたメンバーのみがエクスポートされます (自動的にエクスポートされるものはありません)。

  • Export-ModuleMember呼び出しは、自分自身をエクスポートする要素の定義のに来る必要があるため、モジュール定義の最後に配置するのが最適です。

  • 現在のセッションにインポートされるエクスポートされたメンバーのセットをモジュールの関数のサブセットに制限する場合は、のパラメーターを使用できます。New-Module-Function

    • モジュールが現在のセッションでのみ使用されている場合、 と組み合わせNew-Module -Functionても意味がありませんExport-ModuleMember-Functionまた、使用すると、関数以外のメンバーが現在のセッションにインポートされなくなることにも注意してください。
    • 既定のエクスポート動作と組み合わせると、スクリプト ブロック内で関数名を使用して明示的に呼び出す代わりにNew-Module -Function 効果的に使用できますが、2 つのメカニズムが異なることを理解することが重要です。Export-ModuleMember

variable をエクスポートするには、次の$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().FullNameNoteProperty[System.Management.Automation.PSNoteProperty]

同様に、エクスポートされた関数 は、新しい (非表示の) モジュールのコンテキストで動作し、その変数を参照Fooするタイプのメンバー (メソッド) として表示されます。 (余談ですが、隠しモジュールにアクセスするために使用できます。)ScriptMethod
$newObj.Foo.Script.Module

対照的に、エクスポートされたエイリアスは一見無視されます。

警告: 異なる型のメンバーを同じ名前でエクスポートしないでください (たとえば、同じ名前の関数と変数を定義しないでください)。アクセスできるのはそのうちの 1 つだけです。

于 2016-06-23T01:46:19.580 に答える