NetTCPIP missing from Get-Modules for one minute - powershell

Why does Get-Module not show all the installed Modules?
Some PCs don't have the NetTCPIP module installed. Mine does, but when I open a new PowerShell ISE window
Get-Module | Where-Object Name -eq 'NetTCPIP' | Format-Table
Returns blank.
After one minute it returns:
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Manifest 1.0.0.0 NetTCPIP {Find-NetRoute, ...}
The strange thing is:
Get-Command -Name Test-NetConnection
Always shows that the command exists in the Source: NetTCPIP.
Now the even strange thing is that on a Server OS running the same version of PowerShell, never shows the NetTCPIP module but does have the command Test-NetConnection.
Why does Get-Module not show all the installed Modules?

Get-Module by default lists only the modules which are currently imported. If you want to see all the modules, you can use Get-Module -ListAvailable.
Starting with PowerShell 3.0, modules are dynamically imported first time you use the cmdlet from that module. So if you test the cmdlet to see if it exists (or you use Get-Command Test-NetConnection), PowerShell silently imports the module and it's displayed next time you use Get-Module.

Related

Import PowerShell module from within some subfolders

Although there are already plenty of questions and blogs regarding PowerShell module imports, I did not found any that would answer my question.
I'm trying to import modules which are grouped within subfolders without adding all those subfolders to the $env:PSModulePath. Example of the folder structure:
...\WindowsPowerShell\Modules\
...\WindowsPowerShell\Modules\Avengers
...\WindowsPowerShell\Modules\Avengers\ModuleHulk\ModuleHulk.psd1
...\WindowsPowerShell\Modules\Avengers\ModuleThor\ModuleThor.psd1
...\WindowsPowerShell\Modules\X-Men
...\WindowsPowerShell\Modules\X-Men\ModuleProfX\ModuleProfX.psd1
...\WindowsPowerShell\Modules\X-Men\ModuleMagneto\ModuleMagneto.psd1
...\WindowsPowerShell\Modules\FantasticFour
...\WindowsPowerShell\Modules\FantasticFour\ModuleMisterFantastic\ModuleMisterFantastic.psd1
...\WindowsPowerShell\Modules\FantasticFour\ModuleInvisibleWoman\ModuleInvisibleWoman.psd1
According to the Microsoft Docs the module .psd1 filename has to be the same as the module folder name. This is satisfied above. The modules have to be within a location of the $env:PSModulePath, all good.
Unfortunately, PowerShell fails to import these modules:
PS> Import-Module ModuleHulk
Import-Module : The specified module 'ModuleHulk' was not loaded because no valid module file was found in any module directory.
At line:1 char:1
+ Import-Module ModuleHulk
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (ModuleHulk:String) [Import-Module], FileNotFoundException
+ FullyQualifiedErrorId : Modules_ModuleNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand
PS>
However, recently I found out one can also import modules using the fairly new using module statement (since PowerShell Version 5). For doing that I could add the following code at the very beginning in my scripts or execute that even in the console:
#Requires -Version 5
using module ModuleHulk
PS> using module ModuleHulk
PS>
No issue, all good, so the module itself is fine and can be imported as usual. But, this seems to be a hacky solution and it needs at least PowerShell 5. Now the question:
Is there any way to achieve that using the usual Import-Module cmdlet, without adding all the subfolders to the $env:PSModulePath?
I found one possible solution thanks to another SO question: Import-Module works only when piped from Get-Module.
The Import-Module cmdlet also accepts one or more [PSModuleInfo] objects, which are what Get-Module returns. So one can do the following:
Get-Module ModuleHulk -ListAvailable | Import-Module
PS> Get-Module ModuleHulk -ListAvailable
Directory: ...\WindowsPowerShell\Modules\Avengers\
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Manifest 1.0.0 ModuleHulk
PS> Get-Module ModuleHulk -ListAvailable | Import-Module
PS> Get-Module ModuleHulk
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Manifest 1.0.0 ModuleHulk {...}
PS>
And it worked! If anyone knows why the Get-Module cmdlet finds the modules in a different way than Import-Module, please let me know.

What is the purpose of ImportSystemModules?

What is the purpose of ImportSystemModules? Using help ImportSystemModules -Full produces an empty shell description.
PS 09:12 C:\src
>get-command *module*
CommandType Name Version Source
----------- ---- ------- ------
Function Find-Module 2.2.1 PowerShellGet
Function Get-InstalledModule 2.2.1 PowerShellGet
Function **ImportSystemModules**
Function InModuleScope 3.4.0 Pester
Function Install-Module 2.2.1 PowerShellGet
...
From Roger Lipscombe's blog, it used to do the following:
This runs Powershell.exe -ImportSystemModules, which, in turn, runs the ImportSystemModules command. You can call this command as part of your profile, if you want these modules loaded each time you run PowerShell.
Various places on the Internet state that it loads the available modules from C:\Windows\System32\WindowsPowerShell\v1.0\Modules. Among these are modules for managing IIS, Hyper-V, etc.
It turns out that it also loads snap-ins from C:\Users\rogerl\Documents\WindowsPowerShell\Snapins
However, according to another SO answer:
The -ImportSystemModules switch has no impact in v3, looks like it is going away.
And the Powershell changelog states for v6 beta 9 states the argument has been removed entirely:
Remove parameters -importsystemmodules and -psconsoleFile from powershell.exe. (#4995)
And indeed, running Get-Command ImportSystemModules on Powershell Core v6 cannot find the command anymore:
> Get-Command ImportSystemModules
Get-Command : The term 'ImportSystemModules' is not recognized as the name of a cmdlet, function, script file, or operable program.
As to why it's still there and defined in v5.1 and earlier? Perhaps it's for backwards compatibility, v2 compatibility was guaranteed for a long time.

What is the difference between Get-InstalledModule and Get-Module -ListAvailable?

As far as I can tell they do the same, so what is the reason to use one over the other?
(Sorry, SO question rule engine - have no idea what else to say)
Get-InstalledModule is part of PowerShellGet and will list installed modules using Install-Module cmdlet, But Get-Module -ListAvailable shows modules from all locations mentioned in $env:PsModulePath location.
Please, observe:
C:\> (Get-InstalledModule xyz.ps.core).RepositorySourceLocation
http://devstatic.xyz.com/prdnuget/nuget
C:\> (Get-Module xyz.ps.core -ListAvailable).RepositorySourceLocation.AbsoluteUri
http://devstatic.xyz.com/prdnuget/nuget
file:///C:/Users/mkharitonov/LocalTestPSRepository
The module xyz.ps.core was installed both times using Install-Module. Only once it was installed from a local repository and the other time - from a remote NuGet repository.
In both cases the module is installed into the system location, i.e. it is in PSModulePath. What does matter, apparently, is whether it was downloaded from a remote location.
I wish Microsoft documentation explained it and provided a rationale for having this method.
Get-InstalledModule will list installed modules using Install-Module and which are not naively installed. However Get-Module -ListAvailable shows modules from all locations mentioned in $env:PsModulePath location.
See below Snip for reference :
*PS C:\Users\xyz> Get-InstalledModule
`PS C:\Users\xyz> Get-Module -ListAvailable
Directory: C:\Program Files\WindowsPowerShell\Modules
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 1.0.1 Microsoft.PowerShell.Operation.V... {Get-OperationValidation, Invoke-OperationValidation}
Binary 1.0.0.1 PackageManagement {Find-Package, Get-Package, Get-PackageProvider, Get-Pac...
Script 3.4.0 Pester {Describe, Context, It, Should...}
Script 1.0.0.1 PowerShellGet {Install-Module, Find-Module, Save-Module, Update-Module...
Script 2.0.0 PSReadline {Get-PSReadLineKeyHandler, Set-PSReadLineKeyHandler, Rem...
Directory: C:\Windows\system32\WindowsPowerShell\v1.0\Modules
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Manifest 1.0.0.0 AppBackgroundTask {Disable-AppBackgroundTaskDiagnosticLog, Enable-AppBackg...*`
However if the module is not installed both will throw same exception.
PS C:\Users\Asim> $Error.Exception.Message[-1]
Unable to find type [Microsoft.PowerShell.Commands.PowerShellGet.Telemetry]
.

Get-RDUsersession is not recognized as the name of a cmdlet

I have problems running a script with Powershell in Windows 7.
The script just retrieves a list of all connected user in terminal server in order to connect to them via "mstsc.exe". The problem is that when I run cmdlet "Get-RDUsersession" it returns that it is not recognized as the name of a cmdlet.
I already knew that it could be an error because before running this cmdlet, I had to install the RSAT administrative tools for windows in order to have all of the modules dedicated to "remotedesktop" and "active directory".
In fact, I've done both Windows 7 and Windows 10, but in Windows 10 it works just fine, while Windows 7 that error came up.
Moreover, I saw that in the path C:\Windows\system32\WindowPowerShell\v1.0\Modules there is no remote desktop module, while there is in Windows 10.
Is it normal? How can I run that cmdlet in Windows 7?
I've not had Win7 in my environment for years now, so, no way for me to sanitly check directly. However, if you are saying you downloaded and installed the Win7 version of RSAT (there are different installer for WinOS Clinet versions), and RSAT is not in any of the module paths, there are several module paths, then something went wrong with your RSAT install.
Also, of note, PowerShell cmdlets availability differs on WinClient versions, even if you have installed the latest builds. Some cmdlets are only available to the OS version that they were designed for.
If all else fails, you can use Implicit PS Remoting to a new machine and proxy the cmdlets from that machine and use them. In implicit sessions, the cmdlets are actually ran on the remote host, not your local station that you are using them from.
So, if you do the below on your WIn7 and Win10 systems, what are the results?
Get-Command -Name Get-RDUsersession
CommandType Name Version Source
----------- ---- ------- ------
Function Get-RDUserSession 2.0.0.0 RemoteDesktop
Get-Module -Name RemoteDesktop
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Manifest 2.0.0.0 RemoteDesktop {Add-RDServer, Add-RDSessionHost,...
Import-Module -Name RemoteDesktop -Verbose

Cannot find cert: drive or Certificate Provider via Powershell

For some reason, it seems that my install of Windows 10/Powershell 5.0 is missing the Certificate Provider. It seems like I somehow don't even have the Microsoft.PowerShell.Security module that is supposed to be installed with powershell by default and includes the certificate provider. Here is what I get when I run Get-Module (I added post-git sometime ago, maybe I messed it up when I did that?):
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Manifest 3.1.0.0 Microsoft.PowerShell.Management {Add-Computer, Add-Content, Checkpoint-Computer, Clear-Con...
Manifest 3.1.0.0 Microsoft.PowerShell.Utility {Add-Member, Add-Type, Clear-Variable, Compare-Object...}
Script 0.7.1 posh-git {Add-PoshGitToProfile, Add-SshKey, Enable-GitColors, Get-A...
Script 1.2 PSReadline {Get-PSReadlineKeyHandler, Get-PSReadlineOption, Remove-PS...
and here is what I get when I run Get-PSProvider:
Name Capabilities Drives
---- ------------ ------
Registry ShouldProcess, Transactions {HKLM, HKCU}
Alias ShouldProcess {Alias}
Environment ShouldProcess {Env}
FileSystem Filter, ShouldProcess, Credentials {C, D, E}
Function ShouldProcess {Function}
Variable ShouldProcess {Variable}
Is there anyway that I can reinstall PowerShell or add this provider/drive to my build without reinstalling Windows entirely? Something very fishy seems to have happened to my machine and I'd really rather not do a full reinstall if not absolutely necessary.
I came to find the same issue.
I my case the problem was the PSModulePath environment variable did not have the right paths in it.
I got the same error when running a custom powershell action during an MSI install. Maco1717's answer pointed me in the right direction. Turns out the PSModulePath was different when Powershell was running in Installer context. The fix was to load the proper paths from environment variables like this, at the beginning of the script:
$env:PSModulePath = [Environment]::GetEnvironmentVariable('PSModulePath', 'Machine')
Another very special case appears to be when using PowerShell 5.1 which ends up loading the Microsoft.PowerShell.Management module from PowerShell 7.0.
In normal circumstances $env:PSModulePath should not contain the path to the PS7 modules, but it did for me. I do not fully understand why yet, has something to do with a custom host application for PowerShell.
So this is what happened for me:
> Import-Module pki
> Get-Module | Select-Object -Property Name,Path
Name Path
---- ----
Microsoft.PowerShell.Management C:\program files\powershell\7\Modules\Microsoft.PowerShell.Management\Microsoft.Powe...
pki C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\pki\pki.psd1
This is mixing PS7 with PS5.1 modules, which is not good. I ended up manually patching $env:PSModulePath, removing the PS7 module path. After that, running the same code again and it worked fine:
Name Path
---- ----
Microsoft.PowerShell.Management C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Management\M...
pki C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\pki\pki.psd1