Get-Module -ListAvailable doesn't display my module - powershell

I've created a module manifest .psd1 file and I've used Test-ModuleManifest on it which returns nicely and shows the two CmdLets in the binary C# .dll.
The manifest file is in a folder under c:\Program Files\WindowsPowerShell\Modules but when I run Get-Module -ListAvailable it is not showing.
If I run Get-Module it is not showing.
If I run one of the CmdLets then the module is automatically imported and shows when I next run Get-Module.
What am I misunderstanding?? Why doesn't it show as available?
Update
Just done this again with a script module, psm1 and psd1 on a different machine, and same problem. It doesn't show as available and yet posh-git which seems to be setup in a similar way, does.

Okay, the script module does now show up after I fixed a version inconsistency between the version in the manifest and the subfolder name I'd placed it in.
Came in handy:
Test-ModuleManifest

Related

How can I ensure that a 3rd party module is loaded in my custom script module?

I have a custom script module and one of the functions depends on the AWSPowerShell module. I attempted to put Import-Module AWSPowerShell inside that function, but when this runs on the server it fails and says no valid module is found. If I try Import-Module AWSPowerShell from the command line on the same server running as the same user it works fine. There seems to be something wrong with calling Import-Module from inside another module.
I saw that NestedModules can be used to specify dependencies so I added NestedModules #('AWSPowerShell') to the module manifest and removed the Import-Module AWSPowerShell from the function that needs it.
Now the error about AWSPowerShell happens at the point where I import my own custom module from the calling script.
The exact error is: Import-Module : The module to process 'AWSPowerShell', listed in field 'NestedModules' of module manifest 'C:\Program Files\WindowsPowerShell\Modules\...MyModule.psd1' was not processed because no valid module was found in any module directory.
I did notice that the AWSPowerShell module is installed in a different folder path than my custom module. My module is in C:\Program Files\WindowsPowerShell\Modules and AWSPowerShell is in C:\Program Files (x86)\AWS Tools\PowerShell.
How can I set this up so that AWSPowerShell can be loaded for use inside my module?
Update
I made a copy of the AWSPowerShell module folder under C:\Program Files\WindowsPowerShell\Modules and now the module imports successfully using the NestedModules method. Everything I saw about NestedModules appeared to be for combining modules that were being developed for a bigger solution. I'm not sure about using this technique for importing a 3rd party module like this. I may be misusing this feature.
The NestedModule module-manifest (.psd1) entry is for modules that are bundled with your module and available in your module's code only.
RequiredModules is for importing independently pre-installed modules, which are imported into the global scope when your module is imported, which means that their commands are also available to the caller.
Note: This answer shows how to specify RequiredModules modules to be installed on demand by declaring them as external dependencies, but the limitation appears to be that both the module and its dependency must come from the same repository and must be installed with Install-Module.

Copying MSOnline PowerShell module as a workaround

I am in a tricky situation where I need to install the MSOnline PowerShell module on a PC and it needs to install NuGet first. Unfortunately, the company firewall does not trust the NuGet website, so the PowerShell cmdlets fail at installation.
I was wondering whether I could simply copy a directory containing the MSOnline module from one PC to my target PC. Is this a viable workaround? Or is there another workaround?
I understand that ideally, I should try to have the website whitelisted, but there is a question of timing here.
As exlpained in the comment of #TheMadTechnician you can copy the module from the $env:PSMdulePath the your requested target machines.
If you've multiple machines for module distribtion you can setup your own private Powershell gallery via a network share as explained here (if that's possible in your company). Based on that multiple machines can use the Get-PSRepository, Find-Module -Repository MyRepository, Install-Module -Name MyModule -Repository MyRepository ,.. cmdlets for module administration. I'm using this a private Powershell gallery to distribute some Git tools about multiple dev-machines. You could also publish own Powershell modules in this gallery, in the background NuGet is used. So your machine with access to NuGet could store the newest module via Save-Module (maybe via a background job) and re-publish it to your private gallery.
You should also check if the MSOnlinemodule has any RequiredPackages that you also need to copy. You can do this via (where I used PowerShellGet as example):
PS C:\> (Get-Module -ListAvailable | ? Name -eq PowerShellGet ).RequiredModules
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 1.0.0.1 PackageManagement
Maybe this helps.
From a computer that has access you could use the Save-Module cmdlet to save the module to a path, then copy that folder to the machine in question that's blocked. Then you can either place the folder in the $env:PSModulePath, or load it explicitly with the full path to the folder.
On a computer that has access to the PowerShell Gallery you can run:
Find-Module MSOnline|Save-Module -Path $home\Downloads
Then copy the MSOnline folder from your downloads folder on that computer to the target computer, and place it in one of the folders listed in $env:PSModulePath, or when you want to load the module you can do it explicitly by defining the path to the module.

TFS vNext Powershell build step is using older version of Powershell module

a build with Powershell++ (it comes from Extension Utilities Pack) step keeps failing when I try to run task containing following code Copy-Item -FromSession $cs to copy items from different machine. The error message is
A parameter cannot be found that matches parameter name 'FromSession'.
However, the code does not fail when run from PS console when I'm logged to that machine.
Then I included
(get-command copy-item).Version.ToString()
(get-command copy-item).ModuleName.ToString()
And got version 3.1.0.0 and module Microsoft.PowerShell.Management in PS console and 3.0.0.0 in TFS build step output (module is the same). The version of Powershell is identical in both - 5.0.10586.117.
Looks like the Powershell that is running inside TFS is using different modules.
Can anybody help? Thanks.
Shame on me for not knowing enough about Powershell providers. When wildcard was included in the source path I got this error, without the wildcard it worked fine.
The FromSession parameter is available in PS v5 and not limited to Microsoft.PowerShell.Management 3.0.0.0 (but that is still a mystery to me).

Create pure powershell Nuget module for PowerShellGet

What I want
I want to publish number of PowerShell scripts as Nuget package to be used on build systems.
I want to use PowerShellGet to do installation work for me and version management.
I don't want those scripts to be part of any Visual Studio solution, but as standalone scripts.
Usage scenario
On any system, with configured Nuget provider user executes:
Install-Module MyModule
From that moment all exports from that module permanently available for this user.
Also user can call that command again to update version of those scripts.
What I've done
You can find current state of package here: GitHub
I've added and configured Nuget provider to our local Nuget server
To do this call Get-PackageProvider -Name NuGet -ForceBootstrap and Set-PSRepository -Name My_Nuget_Repo -SourceLocation http://my-nuget/api -InstallationPolicy Trusted
Created proper module, which can be imported locally by Import-Module
Created and published Nuget package with that module
Problem
I can install that package by Install-Module cmdlet and I can see it later in Get-InstalledModule list.
But, no functions are available.
Also, no matter what, but Install-Module not calling any of scripts from my package:
Not calling ScriptsToProcess from MyModule.psd1
Not calling Install.ps1 from tools folder
Not calling Init.ps1 from tools folder
Cmdlets exported by module not available and module can't be imported by Import-Module
(Same package works properly when installed from Visual Studios Install-Package MyModule, scripts are called, PowerShell module is imported).
Investigation
Since PowerShellGet is based on OneGet it seems that problem is in Install-Package cmdlet (which is called inside Install-Module cmdlet).
When I'm executing Install-Package MyModule from Visual Studio Install.ps1 and Init.ps1 are called. But same command from pure PowerShell doing nothing.
After long reverse engineering I've found the root cause
Technical reason
Magical tag PSModule has to be added to <Tags> in nuspec file.
Real reason
You shouldn't create nuspec file and pack nuget package manually at all. Use Publish-Module cmdlet instead.
How to do it properly
I've updated powershellget-module GitHub with:
Example of minimal module which can be published
A way how to use local folder as Nuget feed
Publishing, installation and usage of that module
Reference script with no dependencies which does it all locally, so you can study it
Check it out.

TFS post build powershell script not seeing commands from imported module

We have a TFS build process using a custom template. The build works fine with the crm solution files successfully being created. We are then attempting to run a powershell script on the post build. This script imports a module. But the commands in the module are not being exposed. Whenever we attempt to invoke a command, we get an error. Along the lines of
The term 'Get-XrmSolution' is not recognized as the name of a cmdlet,
function, script file, or operable program.
It doesn't matter which command we use in that module, we get the same kind of error.
To troubleshoot, we have logged onto the build server under the identity of the build account and can successfully run the script we are attempting to run.
Putting some more output into the script to troubleshoot...
Get-Module lists Xrm.Framework.CI.PowerShell. - Good.
Get-Command -Module "Xrm.Framework.CI.PowerShell" returns nothing. From the console, a number of commands are listed.
Is there something we need to do with the running of powershell post build scripts to enable the contents of an imported module to be seen?
Watch out for the bitness of PowerShell invoked by MSBuild and likewise, the bitness of MSBuild launched by Visual Studio. Certain modules only run in either 32-bit or 64-bit PowerShell and not both. You want to make sure the correct version of PowerShell is getting launched.
IIRC you have to explicitly import the module with no assumption of being loaded on user profile, nor on the script path.
Suppose Module1.psm1 is in the same folder as your script, use something like
Import-Module (Join-Path (Split-Path -Parent $MyInvocation.MyCommand.Definition) 'Module1.psm1')
I had the same problem.
The module was loaded in the 'C:\Program Files\WindowsPowerShell\Modules' folder (64 bits).
It all seemed fine when I logged on as the user, but it failed during TFS build.
Solution: I had to uninstall the module in PowerShell 64 bit and re-install in PowerShell 32 bit.
The module was then installed in 'C:\Program Files (x86)\WindowsPowerShell\Modules' folder.