Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get-Module -ListAvailable skips module found in PSModulePath #8125

Closed
cormacpayne opened this issue Oct 25, 2018 · 7 comments · Fixed by #8777
Closed

Get-Module -ListAvailable skips module found in PSModulePath #8125

cormacpayne opened this issue Oct 25, 2018 · 7 comments · Fixed by #8777
Assignees
Labels
Issue-Bug Issue has been identified as a bug in the product Resolution-Fixed The issue is fixed. WG-Engine core PowerShell engine, interpreter, and runtime

Comments

@cormacpayne
Copy link

Installing the Az module from the PowerShell Gallery will install the base Az module, as well as all other submodules (e.g., Az.Compute, Az.Sql, etc.) that it requires -- however, this module appears to be skipped when running Get-Module -ListAvailable, whereas all of the submodules appear.

Steps to reproduce

> Install-Module -Name Az -Repository PSGallery -Force

> Get-Module -Name Az -ListAvailable

Expected behavior

> Get-Module -Name Az -ListAvailable


    Directory: C:\Program Files\PowerShell\Modules


ModuleType Version    Name                                PSEdition ExportedCommands
---------- -------    ----                                --------- ----------------
Script     0.4.0      Az                                  Core,Desk 

>

Actual behavior

> Get-Module -Name Az -ListAvailable
>

Environment data

> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      6.1.0
PSEdition                      Core
GitCommitId                    6.1.0
OS                             Microsoft Windows 10.0.17763
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
@anmenaga
Copy link
Contributor

@rjmholt for comment.

@daxian-dbw
Copy link
Member

Looked into the code, and this is because Az is a valid culture and powershell believes its a local directory just like en and skipped it ...

LCID             Name             DisplayName
----             ----             -----------
44               az               Azerbaijani

dir = Path.GetFileName(dir);
// Use some simple pattern matching to avoid the call into GetCultureInfo when we know it will fail (and throw).
if ((dir.Length == 2 && char.IsLetter(dir[0]) && char.IsLetter(dir[1]))
||
(dir.Length == 5 && char.IsLetter(dir[0]) && char.IsLetter(dir[1]) && (dir[2] == '-') && char.IsLetter(dir[3]) && char.IsLetter(dir[4])))
{
try
{
// This might not throw on invalid culture still
// 4096 is considered the unknown locale - so assume that could be a module
var cultureInfo = new CultureInfo(dir);
return cultureInfo.LCID == 4096;
}
catch { }

@rjmholt
Copy link
Collaborator

rjmholt commented Oct 26, 2018

Wow, what's the situation this is intended to avoid? Is there an extra check we can do, like check if the dirname matches the module name?

@iSazonov iSazonov added Issue-Bug Issue has been identified as a bug in the product WG-Engine core PowerShell engine, interpreter, and runtime labels Oct 26, 2018
@SteveL-MSFT
Copy link
Member

@rjmholt looks like an optimization with the assumption that directories named after locales don't contain modules. Perhaps we can just remove that bit of code and see what the perf difference is.

@SteveL-MSFT SteveL-MSFT self-assigned this Jan 29, 2019
@iSazonov iSazonov added the Resolution-Fixed The issue is fixed. label Feb 21, 2019
@nexocentric
Copy link

nexocentric commented Mar 29, 2022

I'm currently dealing with issues on related to this bug. Regardless of where it is fixed, what would be a viable work around for someone running into this issue.

I've searched quite a bit on the web and the threads related to this are right on the nose in terms of problems, but there are no solutions.

In my psd1 file, if I specify RequiredModules = @('Az') I run into the issue.

I do not want to specify each Az individual model as I am building against all of it and the expectation is that someone will have this installed locally.

What options do I have to specify the required modules? Is there a wild card that I can specify that will separate it from the Cyrillic/Azerbaijan locale that it is hitting?

Maybe even a alias for the Az modules that allows me to specify all of the Az modules.

Thanks for your help and support.

@CoderByTheBay
Copy link

CoderByTheBay commented Dec 17, 2022

@nexocentric After spending much time trying to search the web for a solution to this (as you have) and hitting a brick wall, I finally managed create a workaround to the problem by writing the following cmdlet function:

function Get-AvailableModuleVersions {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory,Position=0)]
        [string] $Name,
        [Parameter(ParameterSetName="Range")]
        [Version] $MinimumVersion,
        [Parameter(ParameterSetName="Range")]
        [Version] $MaximumVersion,
        [Parameter(ParameterSetName="Exact")]
        [Version] $RequiredVersion
    )

    if ([System.Globalization.CultureInfo]::GetCultures([System.Globalization.CultureTypes]::AllCultures) | Where-Object { $_.Name -eq $Name }) {
        $available = $env:PSModulePath.Split(';')`
        | ForEach-Object { Join-Path -Path $_ -ChildPath $Name }`
        | Where-Object { Test-Path -Path $_ }`
        | ForEach-Object { Get-Module -ListAvailable -FullyQualifiedName $_ }
    } else {
        $available = Get-Module -Name $Name -ListAvailable
    }
    
    switch ($PSCmdlet.ParameterSetName) {
        "Range" { $available = $available | Where-Object { (!$MinimumVersion -or ($_.Version -ge $MinimumVersion)) -and (!$MaximumVersion -or ($_.Version -le $MaximumVersion)) } }
        "Exact" { $available = $available | Where-Object { (!$RequiredVersion -or ($_.Version -eq $RequiredVersion)) } }
    }
    return $available
}

It may not be the most elegant solution, but it works in 5.x and does what I need it to do. It also handles exact versions or version ranges.

@kieranwalsh
Copy link

@CoderByTheBay - Thanks. As you say there are loads of people online with this issue but no fixes. Your solution has worked perfectly.

Nice job. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue-Bug Issue has been identified as a bug in the product Resolution-Fixed The issue is fixed. WG-Engine core PowerShell engine, interpreter, and runtime
Projects
None yet
9 participants