Q:

How to properly set function scope within a powershell module?

Background
I'd like all of my scripts and modules to be based on a template script which takes care of some common "housekeeping" tasks.
Some of my modules are interdependent, and so I might load a module within another module, even if temporarily.
However, because the code is templated, the basic initialization functions have the same name.
In my mind, this shouldn't be an issue as long as I scope things properly, but it turns out it is an issue.
Demonstrating the issue
The demo below will have 1 script, which loads a module, which in turn loads another module.
Each module has initialization code that runs when loading he module.

Update: updated the code to demonstrate a bit better why it's structured the way it is, although answer was already accepted.

module.level2.psm1
# module.level2.psm1
# list of modules loaded by template code
$script:LoadModule = $null

# module housekeeping code - called from template code
function ModuleSpecificInitCode {
    Write-Host "Level 2 Code"
}

function Level2ModuleFunction {
    Write-Host "This is why I imported Level 2 module"
}

# module housekeeping code - template code
function TemplateInitCode {
    Write-Host "Level 2 Init"
    $LoadModule | % { Import-Module ".\$_.psm1" }
}

TemplateInitCode 
try {
    ModuleSpecificInitCode 
} catch {
# Error handling
}

module.level1.psm1
# module.level1.psm1
# list of modules loaded by template code
$script:LoadModule = "module.level2"

# module housekeeping code - called from template code
function ModuleSpecificInitCode {
    Write-Host "Level 1 Code"
}

function Level1ModuleFunction {
    Write-Host "This is why I imported Level 1 module"
}

# module housekeeping code - template code
function TemplateInitCode {
    Write-Host "Level 1 Init"
    $LoadModule | % { Import-Module ".\$_.psm1" }
}

TemplateInitCode 
try {
    ModuleSpecificInitCode 
} catch {
# Error handling
}

test.ps1
# test.ps1
Remove-Module module.level*
Import-Module .\module.level1.psm1

When running test.ps1, the output I receive is:
PS>.\test.ps1
Level 1 Init
Level 2 Init
Level 2 Code
Level 2 Code

The Issue / My Question
The issue is the last line. Level 2 code is running instead of level 1 code.
I've tried local, private and script as the <scope>: but whatever I do the Level 1 Code never runs.
What am I missing here, why do all the modules seem to be running in the same namespace?

A:

If you don't explicitly export anything from the module, it all gets exported.
If you want a function to be available only within the module (think of it as a private function, though it's not actually related to the Private: scope in PowerShell), then just export every function except the ones that are internal.
Export-ModuleMember is how you define what you want to be exported. It accepts wildcards, so if you can describe what's public with a pattern, you could do it in one call, but it's ok to call it as many times as you need.
Once the functions are no longer exported, they are not available to code outside the module.
Your examples are a little strange to me, in that you seem to want access to some of the module code outside the module, but want it to be the same name, but I'm not certain.
In that case, for example if Level1 init was supposed to call code in Level2 module, you might consider adding -Scope Local to the Import-Module call itself, but I'm not certain this would help your situation.

