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-FunctionNote 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-Moduleis called in the first instance,functions.ps1as a module doesn't exist - so the code is executed. - Executing
functions.ps1defines the functionMagnetik-Function()in the scope ofcallme.ps1and is able to be called successfully. - On the second and subsequent runs, the module
functionsis 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
.ps1of 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.
Hope you won't mind me commenting here but I came here from google after experiencing this confusing behaviour myself.
This saved me a lot of time and headache so thanks!