This module below returns a empty object . Any suggestions to fix it ?
New-Module -ScriptBlock {
$resourcesDirectory="AA"
.....
$commonProperties = New-Object PSObject -Property @{
ResourcesDirectory = $resourcesDirectory
}
return $commonProperties
} -name GetXXX
Tip of the hat to PetSerAl for his help.
New-Module
by default returns the newly created module, as a [System.Management.Automation.PSModuleInfo]
instance.
By "returns an empty object" I presume you mean that your intent is to have your module export the $commonProperties
variable (which happens to contain a [pscustomobject]
instance, but that is incidental), yet your code failed to do so.
The reason is that in the absence of Export-ModuleMember
calls, variables and aliases - unlike functions - are not automatically exported from a module .
Caveats :
If one or more Export-ModuleMember
calls are present, only the specified members are exported (nothing is exported automatically).
Export-ModuleMember
calls are best placed at the bottom of your module definition, because they must come after the definitions of the elements to export themselves.
If you want to limit the set of exported members that are imported into the current session to a subset of the module's functions , you can use New-Module
's -Function
parameter.
New-Module -Function
with Export-ModuleMember
; also note that using -Function
will prevent non-function members from being imported into the current session. New-Module -Function
effectively provides an alternative to using an explicit Export-ModuleMember
call with the function names inside the script block, though it's important to understand that the two mechanisms differ. To export variable $commonProperties
, you need to call Export-ModuleMember -Variable commonProperties
(note the required absence of prefix $
from the variable name):
$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
Given that New-Module
not only creates a new module but automatically imports it, $commonProperties
is now available in the current session.
Side notes :
By adding switch -ReturnResult
, you can tell New-Module
to return your script block's output rather than the newly created module object (but the module is still imported into the current session).
Applied to your code that would return the value of variable $commonProperties
, due to the return $commonProperties
statement, but, as stated, your script block does not export any members, so the current session wouldn't see the $commonProperties
variable .
Alternatively, switch -AsCustomObject
tells New-Module
to return a [pscustomobject]
instance whose members are the exported members .
Note that normal export rules apply, and that a module is still being created behind the scenes, although it isn't imported .
Applied to your (corrected) code, with exported function Foo
added:
$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
now contains a property named commonProperties
that references the $commonProperty
variable from the new (hidden) module's script block.
Note: Get-Member
misleadingly reports this property's type as NoteProperty
, suggesting a static value, whereas an exported function can potentially alter the value of the underlying variable (although that strikes me as an exotic case). The true type is [System.Management.Automation.PSVariableProperty]
, as $newObj.psobject.properties['commonProperties'].GetType().FullName
reveals, whereas a true NoteProperty
member has type [System.Management.Automation.PSNoteProperty]
.
Similarly, the exported function Foo
surfaces as a ScriptMethod
-type member (method) that operates in the context of the new (hidden) module and sees its variables.
(As an aside: $newObj.Foo.Script.Module
can be used to gain access to the hidden module.)
By contrast, exported aliases are seemingly ignored .
Caveat : Do not export members of different types by the same name (eg, do not define a function and variable of the same name), as only one of them will be accessible.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.