Use PowerShell
The Shell Is Calling
The Shell Is Calling
PowerShell V3 includes a new “feature” – Auto-loading of modules.
Module discovery has been updated to make the exported commands for modules that are not loaded visible in a PowerShell session.
In Version 2, if you run Get-Module on a module that is not loaded but in your PSModulePath, you’ll get some metadata about the module, but nothing about the ExportedFunctions, ExportedCmdlets, ExportedAliases, or ExportedVariables.
Version 3 changes this, allowing Get-Module to retrieve information on all the exported features of the module.
This enables tab completion to complete the names of commands from modules that are not loaded. It also provides information to the PowerShell runtime on where to get the command information from, if the module is not loaded.
So, in Version 3, if you run a command from a module that is not loaded, the runtime will search your PSModulePath for the first command that it can find that matches that name and load the module that command is in for you.
I really don’t care for this feature. I like to be in control of what module I import. The order in which modules are automatically imported depends on your PSModulePath. You don’t get to pick what the order is… User specific PSModulePath entries are first, then machine specific PSModulePath entries. This can cause a host of unexpected problems when there are command name collisions.
For example, the new Hyper-V cmdlets for Windows 8 cannot manage down-level Hyper-V machines, so you might need James O’Neil’s Hyper-V module from Codeplex. Both modules have Get-VM. Since James’ module will be in my user PSModulePath (most likely), unless I specifically load the Windows 8 Hyper-V module, running Get-VM will always load James’ module.
January 6, 2012 - 10:31 am
Of course you CAN pick the order of module loading: you control the PSModulePath — it’s an environment variable you can set permanently in Windows or temporarily in your profile script, etc.
You can also turn it off or control it via $Env:PSDisableModuleAutoLoading = “None”
January 6, 2012 - 10:37 am
The PSModulePath is built by taking the user environmental variable and appending the machine environmental variable, so values set in the user variable will always (by default) precede the machine level paths.
Yes, you can modify that once the shell is started (or in your profile), but that change is not permanent. If it is in your profile, you have to manage whether you want it for all shells or just specific ones, and whether that should be a machine level profile or specific to you.
I’ll likely turn it off for myself, but it can provide an unexpected behavior if you don’t know how it is finding the module to load.
January 6, 2012 - 11:27 am
Well, in your host $Env:PSModulePath is the environment variable… and IF you have it set, whatever you see (or set) there should be what’s being used.
But yes, that’s what I was getting at: you can set both the PSModulePath and PSDiableModuleAutoLoading in your profile but there, they only affects you when your profile is run (ie: not remote sessions). However, if you set them in the “System Properties” control panel in the “Environment Variables” dialog, then it’s basically permanent… and affects either your user or your machine, depending on where you set it.
Personally, I’d encourage people to set their PSModulePath — the default path seems to have changed in PS3 from PS2, but in any case (as a developer, not a sysadmin), I actually like the autoloading