Skip to content

Intended behaviour for Get-Module -ListAvailable -All is not clear, especially for edition-incompatible modules #7297

@rjmholt

Description

@rjmholt

Currently Get-Module -ListAvailable -All has a set of hard-to-describe behaviours that don't seem to align well with each other. An example is the following directory structure:

TopModule
  + TopModule.psd1
  + TopModule.psm1
  + TopModule.dll
  + NestedModule
    + NestedModule.psd1
    + NestedModule.psm1
  + Unused
    + AnotherDir
      + UnusedModule.psm1

Observe the following outputs:

> Get-Module -ListAvailable -All .\TopModule


    Directory: C:\Users\roholt\Documents\Dev\sandbox


ModuleType Version    Name                                PSEdition ExportedCommands
---------- -------    ----                                --------- ----------------
Binary     0.0.0.0    TopModule                           Desk

> Get-Module -ListAvailable -All .\TopModule\*


    Directory: C:\Users\roholt\Documents\Dev\sandbox\TopModule


ModuleType Version    Name                                PSEdition ExportedCommands
---------- -------    ----                                --------- ----------------
Manifest   0.0.1      NestedModule                        Desk


    Directory: C:\Users\roholt\Documents\Dev\sandbox


ModuleType Version    Name                                PSEdition ExportedCommands
---------- -------    ----                                --------- ----------------
Binary     0.0.0.0    TopModule                           Desk
Manifest   0.0.1      TopModule                           Desk
Script     0.0        TopModule                           Desk
> Get-Module -ListAvailable -All ./TopModule/
Get-Module : The specified module 'C:\Users\roholt\Documents\Dev\sandbox\TopModule\' was not found. Update the Name parameter to point to a valid path, and then try again.
At line:1 char:1
+ Get-Module -ListAvailable -All ./TopModule/
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : ResourceUnavailable: (C:\Users\roholt...dbox\TopModule\:String) [Get-Module], FileNotFoundException
+ FullyQualifiedErrorId : Modules_ModuleNotFoundForGetModule,Microsoft.PowerShell.Commands.GetModuleCommand
> mv .\TopModule $PowerShellDevDir\src\powershell-win-core\bin\debug\netcoreapp2.1\win7-x64\publish\Mod
    ules
> Get-Module -ListAvailable -All
...

    Directory: C:\users\roholt\documents\dev\powershell\src\powershell-win-core\bin\debug\netcoreapp2.1\win7-x64\publish\Mod
    ules\TopModule


ModuleType Version    Name                                PSEdition ExportedCommands
---------- -------    ----                                --------- ----------------
Manifest   0.0.1      NestedModule                        Desk
Script     0.0        NestedModule                        Desk

    Directory:
    C:\users\roholt\documents\dev\powershell\src\powershell-win-core\bin\debug\netcoreapp2.1\win7-x64\publish\Modules

ModuleType Version    Name                                PSEdition ExportedCommands
---------- -------    ----                                --------- ----------------
Script     0.0        PackageProviderFunctions            Desk      {New-Feature, New-PackageSource, Write-Error, New-Req...
Script     4.2.0      Pester                              Desk      {Describe, Context, It, Should...}
Script     4.2.0      Pester                              Desk      {Describe, Context, It, Should...}
Script     1.6.0      PowerShellGet                       Desk      {Install-Module, Find-Module, Save-Module, Update-Mod...
Script     1.6.0      PowerShellGet                       Desk      {Install-Module, Find-Module, Save-Module, Update-Mod...
Script     0.0        PSDesiredStateConfiguration         Desk      {ValidateNodeResourceSource, Test-MofInstanceText, Ge...
Script     6.1.0.0    PSDiagnostics                       Core      {Disable-PSTrace, Disable-PSWSManCombinedTrace, Disab...
Script     0.0        PSDiagnostics                       Desk      {Start-Trace, Enable-PSWSManCombinedTrace, Disable-WS...
Manifest   0.0        PSGet.Resource                      Desk
Script     2.0.0      PSReadLine                          Desk      {Get-PSReadLineKeyHandler, Set-PSReadLineKeyHandler, ...
Script     0.0        PSReadLine                          Desk      {Set-PSReadLineKeyHandler, Remove-PSReadLineKeyHandle...
Binary     0.0.0.0    ThreadJob                           Desk
Binary     1.1.1      ThreadJob                           Desk      Start-ThreadJob
Manifest   0.0.1      TopModule                           Desk
Script     0.0        TopModule                           Desk


    Directory: C:\users\roholt\documents\dev\powershell\src\powershell-win-core\bin\debug\netcoreapp2.1\win7-x64\publish\Mod
    ules\TopModule\Unused


ModuleType Version    Name                                PSEdition ExportedCommands
---------- -------    ----                                --------- ----------------
Script     0.0        UnusedModule                        Desk


Summary:

  • Get-Module -ListAvailable -All on relative path ending with slash: file not found error
  • Get-Module -ListAvailable -All on relative path with no slash: only enumerates top level module
  • Get-Module -ListAvailable -All on all files within module dir (relative path): enumerates only modules to 1 depth
  • Get-Module -ListAvailable -All with no arguments, enumerates fully any/all modules below a path on the PSModulePath

The recent CompatiblePSEditions addition makes this behaviour even more complex, since the intent is to hide incompatible modules. For Get-Module -ListAvailable -All, since it currently (in some circumstances) enumerates all modules (not just nested ones but even unused ones), it has to make a choice about whether to show or hide nested psm1/dll/etc modules underneath compatible psd1 modules (i.e. they have no way to declare compatibility themselves, but Get-Module -ListAvailable -All ignores "nestedness").

All of this, I think, means we should discuss what Get-Module -ListAvailable -All should do, what it does do and what it's used for. Ideally we can eventually choose a behaviour (or indeed, set of behaviours) that we can define in an RFC and then implement.

> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      6.1.0-preview.3
PSEdition                      Core
GitCommitId                    v6.1.0-preview.3-138-gf8ccb9f84755023afa52815d8dacc924757e61b1
OS                             Microsoft Windows 10.0.17713
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-Discussionthe issue may not have a clear classification yet. The issue may generate an RFC or may be reclassifResolution-No ActivityIssue has had no activity for 6 months or moreWG-Cmdlets-Corecmdlets in the Microsoft.PowerShell.Core module

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions