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.
Related
I have this myModule.psm1 in modules directory:
function my-test{
$global:PSCommandPath>C:\test.txt;C:\test.txt
}
and this myScript.ps1
my-test
When I run myScript.ps1 with PowerShell ISE, I got path of myScript.ps1 in test.txt file, as i expect.
When I run myScript.ps1 with PowerShell, I got empty test.txt file.
How can I fix it?
This is PowerShell level 100 stuff.
If this is really a module, .psm1 file, then it should be in your modules directory (or directly called from a directory path) and be properly named, then loaded into memory using...
Import-Module -Name 'YourModuleName'
If you are trying to use a function from a .ps1 file, it too must be loaded, by a direct run of the script or dot-sourcing it.
. .\my-test.ps1
At this point, you call any of the functions in the .ps* loaded resource. Your function name and module name should be different things to avoid confusion.
See the help files, web articles, Youtube videos regarding loading .ps* file and running functions from .ps* files. I've provided the link above to Youtube.
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.
I created a Powershell module containing one Cmdlet implemented by C# and some advanced functions provided by a psm1 file. When loading the module, only the functions implemented in advanced functions are exported.
I registered the assembly to load as part of my module and exported the functions:
RequiredAssemblies = #("lib\provider.dll","lib\myCmdlet.dll")
FunctionsToExport = #('New-assemblyFunction','New-advancedFunction')
Also I tried to mix the above functionstoexport with the cmdlettoexport for the assembly provided Cmdlet. All kind of combinations did not show any success:
CmdletsToExport = #('New-assemblyFunction')
If I start the import-module in verbose mode, I can see that the assemblies are being loaded but only functions implemented in advanced functions are being exported. The New-assemblyFunction does not appear anywhere in the verbose report.
I can load the DLL manually (import-module) and the cmdlet is available.
Any clue what's wrong here or how to further analyse? I deblock-file'd all of them.
That's it:
Value of RequiredAssemblieskey not considered as PowerShell modules. You need to use RootModule (ModuleToProcess) or NestedModules key. – PetSerAl
I'm new at working with Powershell (Version 4.0).
I created different modules:
My-Modules
My-Tools
My-HelpfullCommands
In each module directory I have the .psd1 file where I set the FunctionsToExport='My-*' . In the same directory is a .psm1 file with different functions in it.
For Example in the "My-Modules.psm1":
My-GetAvailabilityGroup
My-LastSqlBackup
New-SMOConnection
And in the "My-Tools.psm1":
My-BackupRestoreFromAg
My-GetDbSize
New-SMOConnection
When I check the available commands with Get-Command -Name My-* I find the expected 4 commands.
BUT: When I check Get-Command -Name *SMO*I find the New-SMOConnection two times. Once from the module My-Tools and once from the module My-Modules.
When I try to execute the New-SMOConnection I get the error message New-SMOconnection : The term 'New-SMOconnection' is not recognized as the name of a cmdlet, function... (you know the ObjectNotFound message ;-) )
So, my question is:
Is it possible to "remove" the New-SMOConnection functions, so that they are not visible anymore?
Another question:
Why do the New-SMOConnection functions even show up with Get-Command?
Shouldn't the FunctionsToExport only export the functions that start with My-?
Yes, you can do this using the Remove-Item cmdlet:
Remove-Item -Path Function:New-SMOConnection
I removed all my modules from the directory and opened ISE again to verify that the New-SMOConnection command is gone. Created then a new Module (My-HelpfullCommands) with only the New-SMOConnection in it. In all the other modules, I removed the New-SMOConnection function and copied them back into the modules directory.
Now the New-SMOConnection is declared only once and I can use it for all my modules.
Everything seems to work as expected.
Next I plan to add all my littel helper functions into the "My-HelpfullCommands" module.
I have a psake Task looking something like below (this is simplified for clarity):
Task Invoke-Deploy {
Import-Module "somefunctions.psm1"
Import-Module "morefunctions.psm1"
Set-Something #This is a function defined in morefunctions.psm1
}
Function Set-Something (which is defined in module morefunctions.psm1) attempts to call function Get-Something (which is defined in somefunctions.psm1). When it does I get an error:
The term 'Get-Something' is not recognized as the name of a cmdlet,
function, script file, or operable program.
Interestingly I modified "morefunctions.psm1" to also 'Import-Module "somefunctions.psm1"' and at that point everything worked fine. I would rather not have to do this however as i want my modules to be "loosely-coupled" insofar as they don't need to rely on the existence of other modules.
My knowledge of function/variable scope in Powershell is limited but I thought that functions in two different imported modules lived in the same scope and hence a function in one of those modules would be able to call a function in the other.
I am suspecting that that scope is being affected by the fact that I'm inside a psake task, I'm hoping that someone here can confirm that and also advise on what I should do to fix this. TIA.
I created a script module test-module.psm1:
function Invoke-Test {
Import-Module ".\somefunctions.psm1"
Import-Module ".\morefunctions.psm1"
Set-Something #This is a function defined in morefunctions.psm1
}
and a couple of dummy modules, somefunctions.psm1:
function Get-Something {
'Get-Something'
}
and morefunctions.psm1:
function Set-Something {
Get-Something
'Set-Something'
}
If I call
Import-Module .\test-module.psm1
Invoke-Test
then I get the error "Get-Something : The term 'Get-Something' is not
recognized as the name of a cmdlet, function, script file, or operable
program.". So it looks like a generic PowerShell issue dealing with script
modules. I tried PowerShell v2.0, v3.0, and v4.0.
Perhaps this cannot be resolved in psake without workarounds because it is a script
module. You can use the similar tool
Invoke-Build. It is implemented
as a script and avoids issues like these. It works fine
with this build script:
Task Invoke-Deploy {
Import-Module ".\somefunctions.psm1"
Import-Module ".\morefunctions.psm1"
Set-Something #This is a function defined in morefunctions.psm1
}
It outputs, as expected:
Build Invoke-Deploy ...\.build.ps1
Task /Invoke-Deploy
Get-Something
Set-Something
Done /Invoke-Deploy 00:00:00.0150008
Build succeeded. 1 tasks, 0 errors, 0 warnings 00:00:00.1450083
I ran into this today and got it to work.
In your module "morefunctions.psm1" you need to export the method you want like this:
Export-ModuleMember -Function Set-Something
In your psake task, you need to prepend the module name in front of the method so PowerShell can find it:
Import-Module "morefunctions.psm1"
morefunctions\Set-Something