Save the following as file Test.ps1 and execute it
# define standalone and module function
function MyComm {}
New-Module -ScriptBlock {function FindMyComm {Get-Command MyComm}} | Import-Module
# check for both functions
Get-Command MyComm
Get-Command FindMyComm
# run new function
FindMyComm
Comment: Running commands one by one in interactive console will not generate error. Only from within a script.
Get-Command will run successfully three times.
Get-Command from inside the module fails.

> $PSVersionTable
Name Value
---- -----
PSVersion 6.1.0
PSEdition Core
GitCommitId 6.1.0
OS Microsoft Windows 10.0.17763
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Seems like this issue is related to handling function scopes within command discovery, but I am not quite sure. Dot-sourcing . .\Test.ps1 will run without issues.
Example above is tailored for easy reproducibility. Standard, real life use cases (see https://github.com/PowerShell/platyPS/issues/407), can include normal PowerShell modules, manually or implicitly imported. Also, it does not matter if non-module function (MyComm) is defined directly as above, or dot-sourced from external script. It behaves the same, and Get-Command from inside the module cannot find it.
This is tested and impacts also Windows PowerShell 5.1. Similar example is behaving the same on Ubuntu.
The issue is that function MyComm is defined in a scope that your module by definition cannot see.
Modules see only _global_ (non-module) function definitions, whereas your function is defined in a _child_ of the global scope by virtue of being defined in a _script_.
By dot-sourcing your script from the global scope MyComm is defined globally, that's why the problem goes away.
Hm, that's how I figured it out also, but I find it a bit inconsistent. Your sentence is good definition of this issue:
Modules see only global function definitions
I was presuming FindMyComm will run inside a script scope, although defined in global scope. I was not expecting it will jump up during the execution. Microsoft docs say about functions:
The statements in the list run as if you had typed them at the command prompt.
I don't know if there are differences between functions defined in module or outside of it, in regards to this definition. So, question is: In what scope FindMyComm runs: global or script scope?
What about this example:
# define standalone and module function
function MyComm {}
function Global:FindMyComm {Get-Command MyComm}
# check for both functions
Get-Command MyComm
Get-Command FindMyComm
# run new function
FindMyComm
Now FindMyComm is defined in global scope, but it runs inside of the script scope. I would expect importing it via module to be the same as this example. Function MyComm is not visible in global scope.

As far as I understand, the short of it is (right, @SeeminglyScience?):
Terminology note: I'm using the term _scope domain_ to refer to the distinct variable namespaces inside a session: one default one for all non-module code, and one for each module loaded; they correspond to SessionStateInternal instances, as explained in a blog post by @SeeminglyScience. By _default scope domain_ I mean the namespace for all _non-module_ code (whose root is the global scope). My plan is to suggest these terms be used in an overhaul of the about_Scopes help topic.
Functions execute in whatever scope happens to be current one _in the scope domain they were defined in_, which has the following implications:
Calling a function defined in a module from outside that module runs in [a child scope of] the _originating module's_ current scope, not in the caller's scope.
Calling a function in the same scope domain in which it is defined (i.e., calling a non-module function from non-module code, or calling a module function from inside the same module) runs in [a child scope of] the _caller's_ current scope.
This behavior applies even In _chains_ of calls across scope-domain boundaries (see GlobalFunc example below).
Note that _functions_ create a _child scope_ on invocation, whereas compiled _cmdlets_ do not.
The following code demonstrates these behaviors:
# Define variables to test with.
$global:foo = 'global foo'
$foo = 'script foo'
# A function in the global scope.
function global:GlobalFunc {
"glob func: [$foo]"
}
# Define a non-module function that accesses variable $foo in
# the parent and grandparent scopes.
function NonModFunc {
foreach ($scope in 1, 2) {
try { "scope $scope`: {0}" -f (Get-Variable -ValueOnly -EA Stop -Scope $scope foo) } catch { Write-Warning "No `$foo in scope $scope." }
}
}
# Save the function body as a string, so we can recreate it in the module below.
# Note: We must create a *global* variable so that the script block passed to
# New-Module sees it, given that the script block runs in the new module's scope.
$global:__funcDef = $function:NonModFunc
# Define a function with the same body inside an (in-memory) module.
$null = New-Module -ScriptBlock {
# Same function body as above, only inside a module and with name 'ModFunc'
Invoke-Expression ('function ModFunc {{ {0} }}' -f $__funcDef)
# Define a module function that invokes a global function.
function CallGlobal {
global:GlobalFunc
}
}
'--- non-module func'
NonModFunc
'--- module func'
ModFunc
'--- non-module func from child scope'
& { NonModFunc }
'--- global func via module'
CallGlobal
The above yields (annotated):
# Calling the non-module function from the script scope runs in a child scope of the script scope.
--- non-module func
scope 1: script foo # The function's parent scope is the script scope.
scope 2: global foo # The function's grandparent scope is the global scope.
# Calling the module function from the script scope runs in a child scope of the *module* scope.
--- module func
WARNING: No $foo in scope 1. # The module's root scope has no $foo.
scope 2: global foo # The parent of the module's root scope is the global scope.
# Calling the non-module function from a child scope of the script scope (via a script block,
# & { ... }), runs in a child scope of *that* scope.
--- non-module func from child scope
WARNING: No $foo in scope 1. # The script block's scope has no $foo.
scope 2: script foo # The script block's parent scope is the script scope.
# Calling a module function that in turn calls a global function makes the global function run
# in the non-default (non-module) scope domain's current scope, which is the script scope
# from which CallGlobal was called.
--- global func via module
glob func: [script foo] # CallGlobal was originally called from the script scope.
This issue has been marked as answered and has not had any activity for 1 day. It has been closed for housekeeping purposes.
Most helpful comment
As far as I understand, the short of it is (right, @SeeminglyScience?):
Terminology note: I'm using the term _scope domain_ to refer to the distinct variable namespaces inside a session: one default one for all non-module code, and one for each module loaded; they correspond to
SessionStateInternalinstances, as explained in a blog post by @SeeminglyScience. By _default scope domain_ I mean the namespace for all _non-module_ code (whose root is the global scope). My plan is to suggest these terms be used in an overhaul of theabout_Scopeshelp topic.Functions execute in whatever scope happens to be current one _in the scope domain they were defined in_, which has the following implications:
Calling a function defined in a module from outside that module runs in [a child scope of] the _originating module's_ current scope, not in the caller's scope.
Calling a function in the same scope domain in which it is defined (i.e., calling a non-module function from non-module code, or calling a module function from inside the same module) runs in [a child scope of] the _caller's_ current scope.
This behavior applies even In _chains_ of calls across scope-domain boundaries (see
GlobalFuncexample below).Note that _functions_ create a _child scope_ on invocation, whereas compiled _cmdlets_ do not.
The following code demonstrates these behaviors:
The above yields (annotated):