Export-ModuleMember does not export functions when -Function parameter is used
Prerequisites
- [X] Write a descriptive title.
- [X] Make sure you are able to repro it on the latest released version
- [X] Search the existing issues.
- [X] Refer to the FAQ.
- [X] Refer to Differences between Windows PowerShell 5.1 and PowerShell.
Steps to reproduce
assuming you have a module with psd1 and psm1 file as follows
TestModule.psd1
@{
RootModule = "TestModule2.psm1"
ModuleVersion = "0.0.1"
}
TestModule2.psm1
function Test-Function {
}
function Test-Function2 {
}
function Test-Function3 {
}
Export-ModuleMember -Function "Test-Function2", "Test-Function3"
Expected behavior
when we use Test-ModuleManifest we should see a list containing "Test-Function2", "Test-Function3"
like this
C:\>pwsh -NoProfile -Command Test-ModuleManifest C:\modules\TestModule2\TestModule2.psd1
ModuleType Version PreRelease Name ExportedCommands
---------- ------- ---------- ---- ----------------
Script 0.0.1 TestModule2 {Test-Function2, Test-Function3}
but it does not work like this.
### Actual behavior
```console
instead we see all 3 functions Test-Function, Test-Function2, Test-Function3
C:\>pwsh -NoProfile -Command Test-ModuleManifest C:\modules\TestModule2\TestModule2.psd1
ModuleType Version PreRelease Name ExportedCommands
---------- ------- ---------- ---- ----------------
Script 0.0.1 TestModule2 {Test-Function, Test-Function2, Test-Function3}
this works correctly on Windows PowerShell 5.1
I can make it work on PowerShell core, but I have to change how functions are exported as follows
Export-ModuleMember "Test-Function2", "Test-Function3"
I have to remove -Function parameter name
then it works on both windows powershell 5.1 and powershell core 7.2.5
also I could not find any info that Export-ModuleMember parameters have to be static.
my investigation started when I wanted to pass a variable with functions I want to export.
this idea with variable will not work, I get it, but Export-ModuleMember should work like docs describe, which is not the case currently. docs currently show -Function.
also since Export-ModuleMember has to be static why even bother with it? to me its the main use case for it, lets say I cannot use static list in psd1 file, then I could use dynamic list in psm1 file and use Export-ModuleMember. now in order to mane it work I have to specify statically this list, so I could do this in psd1 file.
I know why you do this, this would have impact on performance of module autoloading, but on the other hand why not put big exclamation in Export-ModuleMember docs
### Error details
_No response_
### Environment data
```powershell
powershell core on windows
$PsVersionTable
Name Value
---- -----
PSVersion 7.2.5
PSEdition Core
GitCommitId 7.2.5
OS Microsoft Windows 10.0.19044
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
windows powershell
$PSVersionTable
Name Value
---- -----
PSVersion 5.1.19041.1682
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.19041.1682
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
### Visuals
_No response_
Export-ModuleMember will only work as you expect if you omit the psd1 module spec entirely. From memory, module exports work something like this:
- If you don't use any
Export-ModuleMemberin the modulepsm1, then apsd1module spec file will determine the exported functions via itsFunctionsToExportkey. - If you do use
Export-ModuleMemberand you have apsd1, then you must also name all of the functions that you want exported in thepsd1as well. You can't omit theFunctionsToExportjust because you've usedExport-ModuleMember.- The odd thing here is that if you use
Export-ModuleMemberin thepsm1, then thepsd1can only export functions that have also been exported withExport-ModuleMember.
- The odd thing here is that if you use
- If you omit the
psd1file then theExport-ModuleMemberstatements are solely responsible for what functions are exported from the module.
This behaviour and interaction between Export-ModuleMember and a PSD1 file with a module is fairly non-obvious and I'm unsure if it's fully documented.
@vexx32 it does not work the way you've described it in second bullet. if you have psd1 you can omit FunctionsToExport you can put * there, it does not matter, you don't have to put any function names there, if you have Export-ModuleMember in psm1 it takes precedence, as long as you set it like I've describe in my issue, which is not consistent with documentation examples.
The 3rd bullet point is not working for me either.
A year later, I've also run into this issue on PowerShell 7.3.6. This is still a problem.