My understanding (and experience of PowerShell v5) is that Modules (.psm1 files) in the Modules\ folder are automatically loaded (unless $PSModuleAutoLoadingPreference is set to none). This appears to be broken in PWSH - at least the alias is not imported/available.
powowshell.psm1
function Invoke-PowowShell {
[CmdletBinding(SupportsShouldProcess)]
[Alias('pow')]
#...code here...
"You have the POWer!"
}
New-Alias -Name pow -Value Invoke-PowowShell
Export-ModuleMember -Function Invoke-PowowShell -Alias pow
Copy the above file to Modules\PowowShell and restart PowerShell Core (PWSH).
I expect Invoke-PowowShell and the alias pow to be available to me in all PowerShell sessions:
PS> pow
You have the POWer!
PS> pow
pow : The term 'pow' is not recognized as the name of a cmdlet, function, script file, or operable program.
...
PS> Invoke-PowowShell
You have the POWer!
So the function Invoke-PowowShell is installed but not the alias pow.
More detail:
PS > Get-Command pow
Get-Command : The term 'pow' 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-Command pow
+ ~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (pow:String) [Get-Command], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand
PS> Get-Command Invoke-PowowShell
CommandType Name Version Source
----------- ---- ------- ------
Function Invoke-PowowShell 0.0 PowowShell
Get-Module:
PS> Get-Module -ListAvailable
Directory: C:\Users\me\Documents\PowerShell\Modules
ModuleType Version Name PSEdition ExportedCommands
---------- ------- ---- --------- ----------------
Script 0.0 Hello Desk Invoke-Hello
Script 0.0 PowowShell Desk Invoke-PowowShell
Name Value
---- -----
PSVersion 6.2.0
PSEdition Core
GitCommitId 6.2.0
OS Microsoft Windows 10.0.16299
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0鈥
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
_Do_ modules autoload when you don't have a PSD1 manifest file? 馃
It's been so long since I wrote a module without a PSD1 that it hasn't occurred to me in forever. I wouldn't _expect_ such a module to autoload, because there's no way to pull the metadata for the module without fully importing it.
They definitely do autoload even without a manifest
I tried this out and it's working for me on Windows 10 with PowerShell 6.2.
However, there's a problem with the function: the attributes fail parsing because there's no param block.
If you call ipmo PowowShell I think you'll see an error message describing this.
When I changed psm1 contents to this:
function Invoke-PowowShell {
[CmdletBinding(SupportsShouldProcess)]
[Alias('pow')]
param() # <---- PARAM BLOCK
#...code here...
"You have the POWer!"
}
New-Alias -Name pow -Value Invoke-PowowShell
Export-ModuleMember -Function Invoke-PowowShell -Alias pow
Everything worked as expected.
For a full working example:
$modDir = ($env:PSModulePath -split ';')[0]
$modPath = Join-Path $modDir 'powowshell'
mkdir $modPath
$psm1Path = Join-Path $modPath 'powowshell.psm1'
New-Item -Path $psm1Path -Value @'
function Invoke-PowowShell {
[CmdletBinding(SupportsShouldProcess)]
[Alias('pow')]
param()
#...code here...
"You have the POWer!"
}
New-Alias -Name pow -Value Invoke-PowowShell
Export-ModuleMember -Function Invoke-PowowShell -Alias pow
'@
pow
Summary:
Invoke-PowowShell workspow does notpow works as expectedApologies, trying this in a new session with only pow did not work and appears to work in Windows PowerShell.
I just checked with PowerShell 6.1.1 and 6.0.5, it looks like this may never have worked in PowerShell 6.
@rjmholt It is not bug. It is "by design". It seems we never analyze module's aliases for performance reasons.
Module manifests work for this purpose.
OK, hard luck for guys like me who are writing their first module. Maybe a warning should be issued that this ain't gonna work properly without a manifest?
It does seem kind of odd to allow the -Alias parameter on the Export-ModuleMember cmdlet if it can't be used. I'm more inclined to think it _is_ actually a bug, especially since it did previously work on Windows PowerShell.
The fundamental problem is that we have to parse a command in the module to work out what it exports. This is not practicable in general:
$body = (Invoke-WebRequest -Uri 'https://mywebsite.com/api/pwsh-export').Body
Export-ModuleMember -Function ($body.Functions)
There's no way to determine what that actually exports without running the code and sending a network request.
It's a contrived example perhaps, but it's (1) quite possible and (2) representative of things like string templating, variable mangling and cmdlet use (Join-Path for example) that might be used.
So we can never actually always determine the exports, it's just not possible. I personally dislike that we try, since it means exports like this are only reliable if you provide concrete values to Export-ModuleMember -- so when you get more clever and it stops working, it's hard to explain why.
@iSazonov I understand the principle, although I'm not entirely sure it's intentional. There's code that seems to do it here:
However, I haven't been able to catch it in the debugger at all.
I've been looking into what it would take to make this work, but the fundamental advice is: Write a module manifest. It's much much better.
I understand the principle, although I'm not entirely sure it's intentional.
I can not find the comment but it was and it seems the comment was from Jason.
Taking into account that currently community has a large number of modules, the rule is to use a manifest. So I think we can close this issue with "By design" until we get important business case.