powershellpowershell-module

How does Powershell Auto-Load Modules?


We learn that Powershell introduced Module Auto-Loading in 3.0 :

... PowerShell imports modules automatically the first time that you run any command in an installed module. You can now use the commands in a module without any set-up or profile configuration, ...

And this is done via PSModulePath.

What the docs fail to explain is how Powershell can detect which commands are in a module without first loading the module.

That is, when I use Import-Module, I "know" that Powershell will execute (??!) the powershell code in my .psm1 file, exporting all functions, ... or whatever I spec with Export-Modulemember.

However, the Auto-Load feature has to know before hand that a certain command is available via a certain module without actually loading the module.

Since we had some misbehaving third party modules in PsModulePath and since we have a very few modules that we wrote ourselves that we like to anchor in PSModulePath, I would very much like to understand how the files in PSModulePath are processed.


Solution

  • This is a partial answer.

    This is done/implemented via Get-Command and this seems to be enabled to "parse" module files without actually executing the PoSh Code there. See below.

    From the powershell docs:

    Implicitly Importing a Module

    ... works on any module in a directory that is included in the value of the PSModulePath environment variable ...

    To support automatic importing of modules, the Get-Command cmdlet gets all cmdlets and functions in all installed modules, even if the module is not imported into the session. ...

    And then:

    Get-Command

    The Get-Command cmdlet gets all commands that are installed on the computer ...

    Get-Command that uses the exact name of the command, without wildcard characters, automatically imports the module that contains the command so that you can use the command immediately. ...

    Get-Command gets its data directly from the command code, unlike ...

    The docs do not explain how this is implemented, but one could possibly look up how it's done in the source code. (I wasn't so far able to find it, despite browsing the sources for a while.)

    Incidentally I find mentioned that Powershell 3 was the first version to expose the AST, so it stands to reason that the posh code does exactly that: Parse the Scripts and inspect their AST in some way to determine if the command is provided.