Cannot import user-defined module - powershell

I have some PowerShell functions and I want to import them into my server 2008 R2 via command Import-Module. So I created a psd1 file and in psm1 I use: Export-ModuleMember -Function "*-*" -Alias *.
However when I execute command:
PS C:\Windows\system32> import-module Myloader -DisableNameChecking -Verbose
VERBOSE: Loading module from path 'C:\Tools\Myloader.psd1'.
VERBOSE: Loading module from path 'C:\Tools\Myloader.psm1'.
I expect it should import my functions but it does not and there is no errors shown up. Then I execute Get-Module -ListAvailable, my function is listed out but there is no information about ExportedCommands
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 3.0 MyLoader
Script 3.0 MyLoader
But when I run it on my local machine it is OK. Have anyone faced with this issue before?
This issue happens on Windows Server 2008 R2, PowerShell 5.0.

When using a module manifest you do the exports inside the .psd1 file. Remove the Export-ModuleMember statement from your .psm1 file and make sure the .psd1 file contains the following lines:
ModuleToProcess = 'MyLoader.psm1'
FunctionsToExport = '*-*'
AliasesToExport = '*'

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.

Why isn't my PowerShell module exporting members correctly and why isn't it exporting Nested Modules?

I'm working on a Quick Module CLI builder. The idea is you have my Module, which has commands like Add-QuickFunction, Add-QuickAlias, New-QuickModule, Remove-QuickCommand, etc.
As you build out the functions, your Modules continue to get built out. The plan is to create an Export-QuickModule and Export-QuickModule command, so that when you're ready to Export your module it's ready to be published, to your organization, or to a public gallery.
So the problem is two-fold.
The exported members do not match the commands in the module
PS C:\WINDOWS\system32> Get-Module -Name QuickModuleCLI
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 0.1.3 QuickModuleCLI {New-QuickModule, Update-QuickModule}
Notice how it only includes 2 Exported commands. This is after I manually added Export-ModuleMember to my local system. Without having Export-ModuleMember, only New-QuickModule appears as exported.
But compare it to the actual list of Commands:
PS C:\WINDOWS\system32> Get-Command -Module QuickModuleCLI
CommandType Name Version Source
----------- ---- ------- ------
Function Add-QuickAlias 0.1.3 QuickModuleCLI
Function Add-QuickFunction 0.1.3 QuickModuleCLI
Function ConvertTo-PowershellEncodedString 0.1.3 QuickModuleCLI
Function Edit-QuickCommand 0.1.3 QuickModuleCLI
Function New-QuickModule 0.1.3 QuickModuleCLI
Function Remove-QuickCommand 0.1.3 QuickModuleCLI
Function Rename-QuickCommand 0.1.3 QuickModuleCLI
Function Reset-QuickCommand 0.1.3 QuickModuleCLI
Function Set-Env 0.1.3 QuickModuleCLI
Function Update-QuickModule 0.1.3 QuickModuleCLI
The Nested Module isn't getting imported into the PowerShell session until after I've imported the Module. I can deal with it by adding Import-Module to my $Profile if I have to, but I just want to make sure I'm not doing anything wrong.
What this means is, after opening a new session, I see the following:
PS C:\WINDOWS\system32> Write-Test
Write-Test : The term 'Write-Test' is not recognized as the name of a cmdlet, function, script file, or operable
program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ Write-Test
+ ~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Write-Test:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
PS C:\WINDOWS\system32> Import-Module QuickModuleCLI
PS C:\WINDOWS\system32> Write-Test
Hello
I use a dynamic self-rolled PowerShell generator to update the psd1 file and add to the FunctionsToExport. You can verify that when I Import-Module, it calls the NestedModules and imports it properly. However, on the computer I use to develop this Module in, I don't need to Import-Module in order for Write-Test to appear in my PowerShell Options. Is this an environmental thing that I have to just "deal with" or is this something you that can be fixed?
The code can be found here: https://github.com/EdLichtman/QuickModuleCLI
And you can try it out yourself with Import-Module QuickModuleCLI
Part 1 - ExportedCommands
Here's a minimal repro for your issue with the ExportedCommands list not matching the result from Get-Command. I distilled it down to this by progressively removing chunks of code from your repo at https://github.com/EdLichtman/QuickModuleCLI until there was nothing left to remove:
MyModule.psd1
#{
RootModule = "MyModule.psm1"
ModuleVersion = "0.1.4"
FunctionsToExport = #(
"Add-MyAlias",
"New-MyModule"
)
}
MyModule.psm1
function global:Add-MyAlias {
write-host "global:Add-MyAlias"
}
function New-MyModule {
write-host "New-MyModule"
}
Interactive
PS> Import-Module .\MyModule\MyModule.psd1 -Force
PS> Get-Module MyModule
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 0.1.4 MyModule New-MyModule
PS> Get-Command -Module MyModule
CommandType Name Version Source
----------- ---- ------- ------
Function Add-MyAlias 0.1.4 MyModule
Function New-MyModule 0.1.4 MyModule
I don't know what the exact implication is when you use global: on an exported function (I'm assuming the function gets imported into the global scope rather than the module scope), but if you remove global: the function will suddenly appear in the ExportedCommands list again:
Part 2 - Importing Modules
PowerShell has a feature that will cause it to search for unknown commands in a set of predefined folder locations. This is called "Module Auto-Loading" and you can enable or disable the feature using the $PSModuleAutoLoadingPreference variable as per About Preference Variables (hint: it's enabled by default).
The locations it searches are defined in an environment variable PSModulePath - see About PSModulePath.
If you want the commands in your module to be discoverable and auto-loaded on first invocation, either install your module in one of the paths already added to the PSModulePath environment variable, or add your module's location to the path.
So to follow up on part 2, it turns out the reason why is related to, in fact it's exactly the same behavior described in this answer:
Invoking functions from nested modules in a script module do not always trigger a module to autoload
My workaround was to add to the FunctionsToExport list, the functions within the NestedModules. Initially I did not think I could export functions that were not directly part of the parent module.

NetTCPIP missing from Get-Modules for one minute

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.

How do I import the correct version of SQLASCMDLETS in PowerShell?

I'm trying to write a PowerShell script to automate some SQL Server Analysis Services tasks. However there are two copies of SQLASCMDLETS on my system:
PS C:\Windows\system32> get-module -ListAvailable -name 'SQLASCMDLETS' | Format-Table -Property Name, Version, Path
Name Version Path
---- ------- ----
SQLASCMDLETS 1.0 C:\Program Files (x86)\Microsoft SQL Server\110\Tools\PowerShell\Modules\SQLASCMDLETS\SQLASCMDLETS.psd1
SQLASCMDLETS 1.0 C:\Program Files (x86)\Microsoft SQL Server\120\Tools\PowerShell\Modules\SQLASCMDLETS\SQLASCMDLETS.psd1
The older version under the \110\ folder contains a bug which incorrectly splits the query into invalid statements and the script fails with an error. I've confirmed that the later version under the \120\ folder works correctly, by changing the extension of the older version and restarting the PS session. However, that is not an ideal solution if this script is to be shared with other users.
Given that both copies have the same name and version number, how can I make sure I use the correct version when I import this module?
Try this:
Import-Module -Name 'C:\Program Files (x86)\Microsoft SQL Server\120\Tools\PowerShell\Modules\SQLASCMDLETS\SQLASCMDLETS.psd1'

'New-AzureStorageContext' is not recognized

I'm trying to run a PowerShell script that functions on a colleague's computer, but is failing on mine on this line:
Set-Variable -Name StorageContext -Value (New-AzureStorageContext -ConnectionString $storageConnectionString)
My error is:
New-AzureStorageContext : The term 'New-AzureStorageContext' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was
included, verify that the path is correct and try again.
At C:\Users\dlogg\Documents\Repos\sd2\PowerShell Scripts\Eco\AddEco.ps1:22 char:43
+ Set-Variable -Name StorageContext -Value (New-AzureStorageContext -ConnectionStr...
I have confirmed I have PowerShell v.3, and I have installed Azure PowerShell with Microsoft Azure SDK and Microsoft Azure PowerShell (Standalone) from Web PI. What do I need to install to use this?
http://msdn.microsoft.com/en-us/library/azure/dn495246.aspx
UPDATE: Per the request below, I have included the output of Get-Module:
ModuleType Name ExportedCommands
---------- ---- ----------------
Script Common {Fetch, Get-BlobContainer, Get-ConfigurationFileName, Get-DeploymentTenantListFileName...}
Script ISE {Get-IseSnippet, Import-IseSnippet, New-IseSnippet}
Manifest Microsoft.PowerShell.Management {Add-Computer, Add-Content, Checkpoint-Computer, Clear-Content...}
Manifest Microsoft.PowerShell.Utility {Add-Member, Add-Type, Clear-Variable, Compare-Object...}
i have same problem with you.
my problem is using the wrong command :"AzureStorageContext".it shoud "AzStorageContext"
You haven't loaded the Azure PowerShell module (hence it is missing from the list you have). When you install the Cmdlets you will also get a new shortcut "Microsoft Azure Powershell" which will automatically load the module for you (and make the Cmdlets available).
If you don't want to do it that way you can import the module into an existing PowerShell session using this command (note that the path to the Azure module may differ depending on the version you have installed).
Import-Module "C:\Program Files (x86)\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Azure.psd1"
Which version of Azure PowerShell module are you using? Have you loaded the Azure module, or just running PowerShell (or via the Azure PowerShell shortcut).
Here is output from Azure PowerShell module 0.8.8.1
PS C:\> Get-Module
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Manifest 0.8.8.1 Azure {Add-AzureAccount, Add-AzureCacheWorkerRole, Add-AzureCert...
Manifest 3.1.0.0 Microsoft.PowerShell.Management {Add-Computer, Add-Content, Checkpoint-Computer, Clear-Con...
Manifest 3.0.0.0 Microsoft.PowerShell.Security {ConvertFrom-SecureString, ConvertTo-SecureString, Get-Acl...
Manifest 3.1.0.0 Microsoft.PowerShell.Utility {Add-Member, Add-Type, Clear-Variable, Compare-Object...}
PS C:\> New-AzureStorageContext
cmdlet New-AzureStorageContext at command pipeline position 1
Supply values for the following parameters:
(Type !? for Help.)
StorageAccountName:
The best way to use Azure PowerShell cmdlets is to start the Azure PowerShell directly from the generated shortcut by the installer. Or use the Import-Module command to import Azure PowerShell module.
For detailed instructions, read the How to: Install and configure Azure Power Shell module. And also check this ServerFault question and answer.
You need to install the azure power shell as in microsoft site
https://learn.microsoft.com/en-us/powershell/azure/install-az-ps?view=azps-1.1.0
It works like a charm
Install Microsoft SDK for PowerShell from the URL - https://azure.microsoft.com/en-in/downloads/
Restart the Windows Machine and try executing the script. It will work as expected