question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Wrong module is auto-loaded when using unqualified cmdlet and multiple modules contain a cmdlet by that name

See original GitHub issue

Prerequisites

Steps to reproduce

  1. Install the VMWare PowerCLI module. Available in the PowerShell gallery at: https://www.powershellgallery.com/packages/VMware.PowerCLI
  2. Open a new PowerShell instance with standard settings (including, but not limited to, PSModuleAutoloadingPreference being undefined). [ Tip: Use -NoProfile if your profile load any module or modifies any settings. ]
  3. Run Get-VM.

Expected behavior

> Get-VM

Name                             State CPUUsage(%) MemoryAssigned(M) Uptime   Status             Version
----                             ----- ----------- ----------------- ------   ------             -------
Ubuntu                           Off   0           0                 00:00:00 Operating normally 11.0
Ubuntu 22.04 LTS                 Off   0           0                 00:00:00 Operating normally 11.0
Windows 10 Enterprise 21H1       Off   0           0                 00:00:00 Operating normally 10.0
.......

Actual behavior

> Get-VM
WARNING: Please consider joining the VMware Customer Experience Improvement Program, so you can help us make PowerCLI a better product. You can join using the following command:

Set-PowerCLIConfiguration -Scope User -ParticipateInCEIP $true

VMware's Customer Experience Improvement Program ("CEIP") provides VMware with information that enables VMware to improve its products and services, to fix problems, and to advise you on how best to deploy and use our products.  As part of the CEIP, VMware collects technical information about your organization’s use of VMware products and services on a regular basis in association with your organization’s VMware license key(s).  This information does not personally identify any individual.

For more details: type "help about_ceip" to see the related help article.

To disable this warning and set your preference use the following command and restart PowerShell:
Set-PowerCLIConfiguration -Scope User -ParticipateInCEIP $true or $false.
Get-VM: 15/05/2023 17:49:56     Get-VM          You are not currently connected to any servers. Please connect first using a Connect cmdlet.

Error details

> Get-Error

Exception             :
    Type              : VMware.VimAutomation.Sdk.Types.V1.ErrorHandling.VimException.ViServerConnectionException
    ErrorId           : Core_BaseCmdlet_NotConnectedError
    ErrorCategory     : ResourceUnavailable
    RecommendedAction : Connect to server.
    Severity          : Error
    TargetSite        :
        Name          : ThrowNotConnectedError
        DeclaringType : VMware.VimAutomation.Sdk.Util10Ps.BaseCmdlet.MessageHelper
        MemberType    : Method
        Module        : VMware.VimAutomation.Sdk.Util10Ps.dll
    Message           : 15/05/2023 17:49:56     Get-VM          You are not currently connected to any servers. Please connect
first using a Connect cmdlet.
    Data              : System.Collections.ListDictionaryInternal
    Source            : VMware.VimAutomation.Sdk.Util10Ps
    HResult           : -2146232832
    StackTrace        :
   at VMware.VimAutomation.Sdk.Util10Ps.BaseCmdlet.MessageHelper.ThrowNotConnectedError()
   at VMware.VimAutomation.Sdk.Util10Ps.BaseCmdlet.ConnectionDispatchHelper.DispatchObjectsHelper(IList`1
connectionList, IList`1 moListFromCmdletParameter, Dictionary`2 runlist, Dictionary`2 connectionIdToUidBourneIdList,
Boolean isConnectionListExplicit)
   at VMware.VimAutomation.Sdk.Util10Ps.BaseCmdlet.ConnectionDispatchHelper.DispatchObjects(ParallelConnectionExecutor
executor, UidDispatchHelper uidDispatchHelper, IList`1 connectionList, Boolean isConnectionListExplicit, IList`1
moListFromCmdletParameter, String moListFromCmdletParameterName, Boolean isServerParameterObnOnly)
   at VMware.VimAutomation.Sdk.Util10Ps.BaseCmdlet.BaseCmdlet.ProcessRecordErrorHandled()
   at VMware.VimAutomation.ViCore.Util10Ps.BaseCmdlet.BaseCmdlet.ProcessRecordErrorHandled()
CategoryInfo          : ResourceUnavailable: (:) [Get-VM], ViServerConnectionException
FullyQualifiedErrorId : Core_BaseCmdlet_NotConnectedError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetVM
InvocationInfo        :
    MyCommand        : Get-VM
    ScriptLineNumber : 1
    OffsetInLine     : 1
    HistoryId        : 2
    Line             : Get-VM
    PositionMessage  : At line:1 char:1
                       + Get-VM
                       + ~~~~~~
    InvocationName   : Get-VM
    CommandOrigin    : Internal
ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1

Environment data

> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.3.4
PSEdition                      Core
GitCommitId                    7.3.4
OS                             Microsoft Windows 10.0.22621
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Visuals

No response

Additional information

This is not the same issue as a function taking precedence over a cmdlet as documented. In this case both names refer to a cmdlet:

> Get-Command -Name "Get-VM" -All | ft -AutoSize

CommandType Name   Version         Source
----------- ----   -------         ------
Cmdlet      Get-VM 2.0.0.0         Hyper-V
Cmdlet      Get-VM 13.0.0.20797821 VMware.VimAutomation.Core

PowerShell decided to use VMware.VimAutomation.Core\Get-VM over Hyper-V\Get-VM contrary to reasonable exepctations. Perhaps because [Version]"13.0.0.20797821" -gt [Version]"2.0.0.0" or maybe because "VMware.VimAutomation.Core" -gt "Hyper-V".

I couldn’t find any documentation saying how the module auto-load feature assigns priorities in such a case so I don’t know if there even is a rule and it’s not arbitrary. Either way - assigning arbitrary priorities is unexpected and assigning the observed priorities is unexpected.

Perhaps it’s difficult to set a rule that would do the expected thing in all use cases. Allowing the user to set precedence of module load is probably the best approach.

Issue Analytics

  • State:open
  • Created 4 months ago
  • Comments:21 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
jhoneillcommented, May 15, 2023

What my reasons are is irrelevant. That’s why I said:

Either way - assigning arbitrary priorities is unexpected and assigning the observed priorities is unexpected.

$Env:PSModulePath says where to search for commands. By default the order is

  1. Modules installed for the current user
  2. Modules installed for all users of the current system
  3. Modules provided with PowerShell (for PowerShell 7)
  4. Models provided with the OS (and also with Windows PowerShell)

Even if you don’t agree with the order I think is correct, doing stuff randomly is unexpected and wrong.

Someone I worked with used to say “What the software does is not random, you just can’t see the pattern” . It is working from most specific definition of the command (user only) to most general (installed with the OS).

Consider what would happen if someone made a module with cmdlets such as Write-Warning and Select-Object. It is idiomatic not to specify their full names, so using them in every module can do anything under the approach you suggest.

Yes, and that is by design - although because they are in the utility module, that will often be loaded by something else. But if you take something like start-transcript you can replace it with your own start transcript command if you so choose. There have been comments in the past that if users can be tricked into installing a malicious module, then it can replace common commands with harmful ones (true) but the ability to replace a command is a key one.

1reaction
ThomasNietocommented, May 18, 2023

I think the enhancement I describe would still be useful for module authors that want to ensure their commands are module qualified without having to import modules with -Force or having to create aliases or module qualifying all commands since the module author doesn’t know what commands are available on the system or loaded.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Specific PowerShell Module Not Autoloading
Im using PowerShell 4 on Windows Server 2012 R2. A specific module, WebAdministration, does not get auto loaded when calling a Cmdlet that...
Read more >
Chapter 8. Using and authoring modules - liveBook · Manning
Beginning with PowerShell v3, modules that are found on the module path will be autoloaded. Modules in folders not on the module path...
Read more >
Resolving PowerShell module assembly dependency ...
PowerShell always loads assemblies into the same context. This presents issues when a module's dependencies conflict with already-loaded DLLs ...
Read more >
How to stop/disable autoload of PowerShell modules...
Hello, it may be nice for most people to have the PowerShell modules loaded as soon as i might type in something that...
Read more >
Windows PowerShell in Action, Third Edition
PowerShell functions. Chapter 7. Advanced functions and scripts. Chapter 8. Using and authoring modules. Chapter 9. Module manifests and ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found