Just getting started on module development, running PS4, and I've run into an... inconsistency... that I'm trying to understand. I've got two test functions, Get-Something and Set-Something in a script module. In my manifest file I specify a DefaultCommandPrefix of 'Test'.
My issue is the function name resolution doesn't result in an executable result if you leave PowerShell up to it's own process.
To begin with I closed all sessions and deleted all files in the CommandAnalysis directory. After starting a session I waited for the CommandAnalysis cache to populate. Then I ran a series of test commands to illustrate how, most of the time, the function name PowerShell registers with tab completion can't be executed because it lacks the 'Test' prefix. Even worse, much of the time tab completion won't recognize the correct (i.e., with prefix) name of the function and honor tab completion for it.
Having just learned of the CommandAnalysis cache I assumed I would see it change as PowerShell 'learned' more about the module because the name resolves differently over time. I've included three files at the end of this post, the module code (ModuleTest.psm1), the manifest (ModuleTest.psd1) and the capture of output to the PowerShell session (ModuleTest.txt). I've tried to include the times I used <tab> and <ret> for tab completion and execution as well as (comments in parenthesis for things I did like starting a new session and checking the CommandAnalysis cache for changes).
An example is, when first starting a session typing 'get-som<tab>' will resolve to 'Get-Something' (prefix 'Test' missing) and typing 'get-test<tab>' won't resolve to 'Get-TestSomething'. Try to execute the 'Get-Something' from tab completion and you'll get the 'name not recognized, blah, blah'.
Now if you type 'get-som<tab>' PowerShell will resolve to 'ModuleTest\Get-Something' - looks promising... but no. Try to execute the 'ModuleTest\Get-Something' from tab completion and you'll still get the 'name not recognized, blah, blah'. Even though the same key strokes resolved differently there were no changes made to the CommandAnalysis cache so I'm lost on why it produces two different (though equally useless) results.
Manually importing the module and sometimes running Get-Command -Module ModuleTest will make tab completion of the function names behave correctly. Is this a known issue with using DefaultCommandPrefix in script modules or is there something I need to include in the manifest to enforce strict name recognition (including the prefix)?
<ModuleTest.psm1>
function Get-Something
{
Write-Host "Get-Something Executed"
}
function Set-Something
{
Write-Host "Set-Something Executed"
}
<ModuleTest.psd1>
@{
# Script module or binary module file associated with this manifest
ModuleToProcess = 'ModuleTest.psm1'
# Version number of this module.
ModuleVersion = '1.0.0.0'
# ID used to uniquely identify this module
GUID = '241877ff-64be-40c8-a603-8d5acf7a48d8'
# Author of this module
Author = 'wb3'
# Company or vendor of this module
CompanyName = ''
# Copyright statement for this module
Copyright = '(c) 2015. All rights reserved.'
# Description of the functionality provided by this module
Description = 'Module description'
# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '2.0'
# 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 = '2.0'
# Minimum version of the common language runtime (CLR) required by this module
CLRVersion = '2.0.50727'
# Processor architecture (None, X86, Amd64, IA64) required by this module
ProcessorArchitecture = 'None'
# 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
# ModuleToProcess
NestedModules = @()
# Default command prefix
DefaultCommandPrefix = 'Test'
# Functions to export from this module
FunctionsToExport = '*'
# Cmdlets to export from this module
CmdletsToExport = '*'
# Variables to export from this module
VariablesToExport = '*'
# 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 ModuleToProcess
PrivateData = ''
}
<ModuleTest.output>
PS C:\Scripts\PowerShell> Get-ChildItem -Path 'C:\Program Files\WindowsPowerShell\Modules' -Recurse<ret>
Directory: C:\Program Files\WindowsPowerShell\Modules
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 3/5/2015 9:06 AM ModuleTest
Directory: C:\Program Files\WindowsPowerShell\Modules\ModuleTest
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 3/5/2015 8:50 AM 2907 ModuleTest.psd1
-a--- 3/5/2015 9:01 AM 140 ModuleTest.psm1
PS C:\Scripts\PowerShell> Get-Module -ListAvailable<ret>
Directory: C:\Program Files\WindowsPowerShell\Modules
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 1.0.0.0 ModuleTest {Get-Something, Set-Something}
PS C:\Scripts\PowerShell> get-som<tab>
PS C:\Scripts\PowerShell> Get-Something<ret>
Get-Something : The term 'Get-Something' 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
+ Get-Something
+ ~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-Something:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
(No change in CommandAnalysis cache)
PS C:\Scripts\PowerShell> get-som<tab>
PS C:\Scripts\PowerShell> ModuleTest\Get-Something<ret>
ModuleTest\Get-Something : The term 'ModuleTest\Get-Something' 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
+ ModuleTest\Get-Something
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (ModuleTest\Get-Something:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
(No change in CommandAnalysis cache)
PS C:\Scripts\PowerShell> get-tes<tab>
PS C:\Scripts\PowerShell> Get-TestSomething<ret>
Get-Something Executed
(New Session)
(No change in CommandAnalysis cache)
PS C:\Scripts\PowerShell> get-tes<tab><ret>
get-tes : The term 'get-tes' 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
+ get-tes
+ ~~~~~~~
+ CategoryInfo : ObjectNotFound: (get-tes:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
PS C:\Scripts\PowerShell> Import-Module ModuleTest<ret>
(No change in CommandAnalysis cache)
PS C:\Scripts\PowerShell> get-tes<tab><ret>
PS C:\Scripts\PowerShell> Get-TestSomething
Get-Something Executed
(New Session)
(No change in CommandAnalysis cache)
PS C:\Scripts\PowerShell> get-tes<tab><ret>
get-tes : The term 'get-tes' 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
+ get-tes
+ ~~~~~~~
+ CategoryInfo : ObjectNotFound: (get-tes:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
PS C:\Scripts\PowerShell> Get-Command -Module ModuleTest<ret>
CommandType Name
ModuleName
----------- ----
----------
Function Get-TestSomething
ModuleTest
Function Set-TestSomething
ModuleTest
(No change in CommandAnalysis cache)
PS C:\Scripts\PowerShell> get-tes<tab>
PS C:\Scripts\PowerShell> Get-TestSomething<ret>
Get-Something Executed
PS C:\Scripts\PowerShell> moduletest\get<tab><ret>
PS C:\Scripts\PowerShell> Get-TestSomething<ret>
Get-Something Executed
William Busby, PMP