Exporting PS Members from Module Fails - powershell

I have a psm1 module with several functions. I only want to expose some of the functions, so I used "Export-ModuleMember -Function " and everything was fine.
Now I want to add a manifest, so I removed the Export-ModuleMember cmdlet and put the function names under the FunctionsToExport section of the psd1 file.
When I import the module, I can tab-complete the functions, but when I try to use them, ps says:
Test-Function : The term 'Test-Function' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
I also tried putting Export-ModuleMember -Function * into the psm1, but that didn't help.
The psm1 and psd1 files are named the same and are in the root of the module.
Thoughts? Thanks.

I found the answer. I had forgotten to un-comment the RooteModule node. Once I did that (and had module.psm1 as the value), the exported commands showed up in the "Get-Module module" output.

I would suspect that PowerShell caching mechanism is involved here. Try to run:
Get-Module -ListAvailable -Refresh
I recommend very good article on that subject written by PowerShell MVP Tobias Weltner.

Related

Does PowerShell import function as module command by naming convention?

I have a PS module and in the .psm1 file for this module all relevant .ps1 files are "dot-sourced", or in my vocabulary: loaded. In one of the .ps1 files, let us say I have a function SetFoo.
If I do an Import-Module I cannot use the SetFoo function. If I list the commands for the module via Get-Command it is not available.
If I change the name of the function to Set-Foo the function is recognized after having done Import-Module and it is listed via Get-Command.
So my question is: is it via function naming convention that Set-Foo is loaded and SetFoo is not? I have googled myself silly, but cannot find anything in the PS docs about this.

How to expose sub module function, from a module

How do you expose a function and an alias from a module, from a sub module
profile.ps1:
Import-Module module_one.psm1
module_one.psm1:
Import-Module module_two.psm1:
module_two.psm1:
Set-Alias readme -Value "Read-Me"
function Read-Me() {
Write-Host "Hello..."
}
Export-ModuleMember -Function Read-Me, readme
I want to be able to call this function from the pwsh terminal, function name or alias?
I get (readme or Read-Me):
Read-Me : The term 'Read-Me' is not recognized as the name of a cmdlet,
function, script file, or operable program. Check the spelling of the name,
or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ co
+ ~~
+ CategoryInfo : ObjectNotFound: (co:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Note: it works for functions in module_one.psm1.
Assuming that you call Import-Module module_one.psm1 and later readme / Read-Me in the same scope domain (either outside a module or from the same (other) module), your code works in principle:
The exported elements of the indirectly imported module are (also) imported into the top scope of the caller's scope domain.
Your problem is that you're trying to export alias readme as a function; you need to use the separate -Alias parameter instead:
Export-ModuleMember -Function Read-Me -Alias readme # Note the -Alias parameter
Also note that in the absence of an Export-ModuleMember call it is all (top-level) functions and aliases (but not variables) that are exported by default, so in your particular case simply omitting the call would have fixed the problem too.
In general, though, it is better to be explicit about what elements are exported, and that is best done via a full-fledged module that is not just a single *.psm1 file, but an entire directory named for the module, housing the *.psm1 file with an associated module manifest, which is a *.psd1 file that describes the module, notably also in terms of its exports.
If such a module is placed in one of the directories listed in $env:PSModulePath, its exported commands can be discovered (e.g., with Get-Command or tab-completion) even before the module is imported, via a feature called auto-loading - see about_Modules.
Note that Import-Module -Global is rarely needed and should generally be avoided, because it makes a module's exported elements available to all loaded modules too, which can have unintended side effects (modules should declare their dependencies explicitly).

Powershell - Export-ModuleMember doesn't work

I'm new with PowerShell and I've just started to create my own module.
I created the script & manifest files and placed them into the directory C:\Program Files\WindowsPowerShell\Modules\ who is one listed of the $env:PSModulePath command.
I can import and remove the module as well but it's not recognized as an applet or command when I try to call one of the function.
I use the Import-Module command :
Import-Module MyModule
My script file is something like this :
function MyFunction() {}
Export-ModuleMember -Function *
And my manifest looks like this :
FunctionsToExport = '*'
Do I need to write all of the exported functions into the manifest ?
Thank you for your help.
Ok so after a few hours I found the answer :
ExportedCommand empty custom module PowerShell
You need to put RootModule = 'MyModule.psm1' into the manifest.
Have a nice day !
for me, the following ( based on Mica's answer) worked:
Change the RootModule as Mica suggested in the psd1 file to the psm1 file.
Use the Import-Module -Force MyModule command
(with the '-Force' flag:
"This parameter causes a module to be loaded, or reloaded, over top of the current one." as said at https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/import-module?view=powershell-7.1#examples)
To export everything:
Module manifest (.psd1):
FunctionsToExport = '*'
Module script file (.psm1):
Export-ModuleMember -Function *
To restrict what gets exported:
Module manifest (.psd1):
FunctionsToExport = 'Foo', 'Bar'
Module script file (.psm1):
Export-ModuleMember -Function Foo, Bar
Note that if quotes are not used in this specific way, it will not work, and no error will be reported.

Powershell module not loading

I am trying to load a PowerShell module that executes a custom cmdlet function but I can't get it to load... I've applied the solutions of several previous questions, but now I'm just going in circles. Here are the specs of what I have done so far and the specific error that returns. Note that as I am new to PowerShell and programming in general, it wouldn't surprise me that my problem isn't a file path issue but a logic error in my actual function:
I created a profile function for a custom cmdlet that allows me to
open project files from two different paths:
function push-project( $project )
{
pushd ~/Documents/Visual Studio 2015/Projects/$project;
pushd ~/Documents/GitHub/$project;
}
New-Alias -Name pp -Value push-project;
I created a module by saving the function as ProfileFunctions.psm1
in the following directory:
~\Documents\WindowsPowerShell\Modules\ProfileFunctions\ProfileFunctions.psm1
To invoke the function, per its syntax, I type in pp $projectName into the PS console window, but the error that returns is standard not recognized:
pp : The term 'pp' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
pp MyFirstApp
~~
CategoryInfo : ObjectNotFound: (pp:String) [], CommandNotFoundException
FullyQualifiedErrorId : CommandNotFoundException
I copied and pasted your code into a Windows 8.1 machine I have here. It worked great (apart from the folder names not existing, since I don't have Visual Studio).
Things off the top of my head that might stop your module from working:
The file is actually called ProfileFunctions.psm1.ps1 or ProfileFunctions.psm1.txt or something.
The Modules folder is saved in someone else's documents folder, or the Public documents folder.
You've accidentally put a space in the folder name (it must be WindowsPowerShell, not Windows PowerShell).
I Think your problem is that the Alias pp is not exported from the module.
You either define the alias outside the module, as supposed to or explicitly export it from the module using.
Export-ModuleMember -Function pushproject -Alias pp
Find more details in this article Unable to Create a Powershell Alias in a script Module

Unable to create a PowerShell alias in a script module

Steps to reproduce:
Create a TestAlias module in \WindowsPowerShell\Modules\TestAlias\TestAlias.psm1 with the following function and alias:
function foo
{ write-output 'foo' }
New-Alias -name bar -value foo
From a PowerShell session:
import-module TestAlias
bar
The term 'bar' is not recognized as the name of a cmdlet, function, script file, or operable program...
You can use
Export-ModuleMember -Function * -Alias *
to export all functions and aliases.
By default, Windows PowerShell modules only export commands (functions or cmdletS), and not variables or aliases.
I'll go into a little more detail about why this is.
The short answers is that aliases, while convenient when writing one liners, are a barrier to understanding a script or a module. They are icing on the cake of a good cmdlet, but the core thing to expose is the good cmdlet. Aliases make it more difficult for a user reading your script to figure out what you're trying to do (Set-Content is a lot easier to understand than sc). Variables can be even worse to expose, as they can easily be set to unexpected values and as there is very little to help a user of your module figure out that they are there. Because commands are easily discoverable (Get-Command -Module FOO) and easier to explore (with Get-Help), the default that a module will export is only commands. As with most other things in PowerShell, you can override it if you choose, but by default commands are the only thing that are exported from a module.
Hope this Helps
Use Export-ModuleMember in the PSM1 file to export the Alias
Export-ModuleMember -function foo -Alias bar