Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variables I listed to export in my powershell module manifest aren't actually exporting

I am creating a script module and using a manifest to export script members and set other module properties. I have followed just about every example manifest I've found and even used New-ModuleManifest to create a baseline manifest with the properties I want, I still cannot get the variables I want to export to actually export.

The intention here is to do all declarations in the manifest without having to use Export-ModuleMember in the module script.

Here is the script module:

#
# Widget.psm1
#

[System.Random]$rGen = New-Object System.Random;
[string]$WidgetBaseName = $null;
[string]$WidgetColor = "Blue";

function Get-WidgetName
{
    param
    (
        [Parameter(Mandatory=$true)]
        [string]$widgetName,
        [switch]$appendRandomNumber
    )

    if (![string]::IsNullOrEmpty($WidgetBaseName))
    {
        $widgetName = $WidgetBaseName + $widgetName;
    }

    if ($appendRandomNumber)
    {
        return [string]::Format("{0}{1:D4}", $widgetName, $rGen.Next(10000));
    }
    else
    {
        return $widgetName;
    }
}

function Get-WidgetBlessing()
{
    return [string]::Format("A thousand blessings upon your {0} widget!", $WidgetColor);
}

And this is the manifest:

#
# Widget.psd1
#

@{

# Script module or binary module file associated with this manifest
RootModule = 'Widget.psm1'

# Version number of this module.
ModuleVersion = '0.0.0.1'

# ID used to uniquely identify this module
GUID = 'c4437164-ea47-4148-97ed-48737bd5824d'

# Author of this module
Author = 'Widget Developer'

# Company or vendor of this module
CompanyName = 'Fictional Company Inc.'

# Copyright statement for this module
Copyright = '(c) 2016 Fictional Company. All rights reserved.'

# Description of the functionality provided by this module
Description = 'Widget Module'

# Minimum version of the Windows PowerShell engine required by this module
# PowerShellVersion = ''

# Name of the Windows PowerShell host required by this module
# PowerShellHostName = ''

# Minimum version of the Windows PowerShell host required by this module
# PowerShellHostVersion = ''

# Minimum version of the .NET Framework required by this module
# DotNetFrameworkVersion = ''

# Minimum version of the common language runtime (CLR) required by this module
# CLRVersion = ''

# Processor architecture (None, X86, Amd64) required by this module
# ProcessorArchitecture = ''

# Modules that must be imported into the global environment prior to importing this module
# RequiredModules = @()

# Assemblies that must be loaded prior to importing this module
# RequiredAssemblies = @()

# Script files (.ps1) that are run in the caller's environment prior to importing this module
# ScriptsToProcess = @()

# Type files (.ps1xml) to be loaded when importing this module
# TypesToProcess = @()

# Format files (.ps1xml) to be loaded when importing this module
# FormatsToProcess = @()

# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
# NestedModules = @()

# Functions to export from this module
FunctionsToExport = @( "Get-WidgetName", "Get-WidgetBlessing" )

# Cmdlets to export from this module
# CmdletsToExport = @()

# Variables to export from this module
VariablesToExport = 'WidgetBaseName', 'WidgetColor'

# Aliases to export from this module
AliasesToExport = '*'

# List of all modules packaged with this module
# ModuleList = @()

# List of all files packaged with this module
# FileList = @()

# Private data to pass to the module specified in RootModule/ModuleToProcess
# PrivateData = ''

# HelpInfo URI of this module
# HelpInfoURI = ''

# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
# DefaultCommandPrefix = ''

}

To check what members get exported, I run the following commands in my PowerShell window:

Import-Module Widget
Get-Module -Name Widget | fl

This is the output. Note the conspicuous absence of any exported variables.

Name              : Widget
Path              : D:\SRE\PowerShell\Widget\Widget.psm1
Description       : Widget Module
ModuleType        : Script
Version           : 0.0.0.1
NestedModules     : {}
ExportedFunctions : {Get-WidgetBlessing, Get-WidgetName}
ExportedCmdlets   : 
ExportedVariables : 
ExportedAliases   : 

Why is this? I'm using the manifest that New-ModuleManifest generated (New-ModuleManifest -VariablesToExport WidgetBaseName WidgetColor). Is that tool broken, or is there something else in the manifest that is causing this behavior?

UPDATE:

I added the following line to the end of the module script:

Export-ModuleMember -Variable WidgetBaseName, WidgetColor

I changed the value of VariablesToExport to '*' in the manifest file.

Now when I import the module and run the check as described above, I get this instead:

Name              : Widget
Path              : D:\SRE\PowerShell\Widget\Widget.psm1
Description       : Widget Module
ModuleType        : Script
Version           : 0.0.0.1
NestedModules     : {}
ExportedFunctions : 
ExportedCmdlets   : 
ExportedVariables : {WidgetBaseName, WidgetColor}
ExportedAliases   : 

... where did my exported functions go?

like image 628
user1956801 Avatar asked Jul 12 '16 21:07

user1956801


2 Answers

So for the sake of completeness and for anybody that lands on this question in the future I am going to sum up the conversation we had in the comments to the OP's question.

All functions are exported from a module by default, no other members exhibit this behavior. It is as if Export-ModuleMember -Function * is implicitly called from within the module. You can then further restrict what functions are exported via the ExportedFunctions key in the module manifest, e.g. ExportedFunctions : {Get-WidgetBlessing, Get-WidgetName}.

If you want to export variables or aliases you have to explicitly add a call to Export-ModuleMember -Variable <what you want to export> or Export-ModuleMember -Alias <what you want to export> in your module. However, once you have added an explicit call to Export-ModuleMember the implicit call to Export-ModuleMember -Function * no longer happens. You have to remember to add Export-ModuleMember -Function * to your module explicitly if you add even one other explicit call to Export-ModuleMember or else your functions will no longer continue to be exported.

like image 124
Jason Boyd Avatar answered Oct 18 '22 21:10

Jason Boyd


Actually noticed the valid response is opposite to documentation.

From Microsoft

FunctionsToExport

Specifies the functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. By default, no functions are exported. You can use this key to list the functions that are exported by the module. The module exports the functions to the caller's session state. The caller's session state can be the global session state or, for nested modules, the session state of another module. When chaining nested modules, all functions that are exported by a nested module will be exported to the global session state unless a module in the chain restricts the function by using the FunctionsToExport key. If the manifest exports aliases for the functions, this key can remove functions whose aliases are listed in the AliasesToExport key, but this key cannot add function aliases to the list. Example: FunctionsToExport = @("function1", "function2", "function3")

VariablesToExport

Specifies the variables that the module exports to the caller's session state. Wildcard characters are permitted. By default, all variables ('*') are exported. You can use this key to restrict the variables that are exported by the module. The caller's session state can be the global session state or, for nested modules, the session state of another module. When you are chaining nested modules, all variables that are exported by a nested module will be exported to the global session state unless a module in the chain restricts the variable by using the VariablesToExport key. If the manifest also exports aliases for the variables, this key can remove variables whose aliases are listed in the AliasesToExport key, but this key cannot add variable aliases to the list. Example: VariablesToExport = @('$MyVariable1', '$MyVariable2', '$MyVariable3')

like image 37
Sam Avatar answered Oct 18 '22 19:10

Sam