Well, not so much a quirk - but an interesting anti-pattern I found in some (poor quality) PowerShell. Documenting the "how and why" so I can refer to it again if needed!
We have two files callme.ps1
and functions.ps1
:
functions.ps1
:
function Magnetik-Function() {
Write-Output "This is Magnetik-Function"
}
callme.ps1
:
Import-Module -Name ($PSScriptRoot + "\functions.ps1")
Magnetik-Function
Note that callme.ps1
incorrectly uses Import-Module
against a .ps1
file (not a module) - that's what exposes the quirk.
PS Z:\> .\callme.ps1
This is Magnetik-Function
PS Z:\> .\callme.ps1
Magnetik-Function : The term 'Magnetik-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.
At Z:\callme.ps1:5 char:1
+ Magnetik-Function
+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Magnetik-Function:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
PS Z:\>
Weird? Why does Magnetik-Function()
work once only?
- When
Import-Module
is called in the first instance,functions.ps1
as a module doesn't exist - so the code is executed. - Executing
functions.ps1
defines the functionMagnetik-Function()
in the scope ofcallme.ps1
and is able to be called successfully. - On the second and subsequent runs, the module
functions
is already known to PowerShell in this session - so is not re-run, thusMagnetik-Function()
is never re-declared and we get failure.
We can also see this by a call to Get-Module
:
PS Z:\> Get-Module
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 0.0 functions
Manifest 3.1.0.0 Microsoft.PowerShell.Management {Add-Computer, Add-Content, Checkpoint-Computer, Clear-Content...}
Manifest 3.1.0.0 Microsoft.PowerShell.Utility {Add-Member, Add-Type, Clear-Variable, Compare-Object...}
PS Z:\>
Note that functions
as a module exists (it takes it's name from functions.ps1
) - but because the file is not a true module (with a file extension of .psm1
) it doesn't export any methods (functions).
-
If needing to bring in a
.ps1
of functions/code - source them like so:. ($PSScriptRoot + "\functions.ps1")
-
When creating actual PowerShell modules, be sure to name such files correctly, with the right file extension - e.g.
functions.psm1
.