Author Posts

September 12, 2018 at 10:52 am

Hi all,

I have followed few guides on how to create a PowerShell module with multiple script files instead of just having one huge psm1 file. Since I placed the module in one of the default locations, I am not sure why the module is not auto-loaded. Please advise!

Here are the steps I followed:

  1. Place the module in the local user`s Document folder:

    C:\Users\\Documents\WindowsPowerShell\Modules\myScripts

  2. Create module file psm1 using the same name as the root folder:

    C:\Users\\Documents\WindowsPowerShell\Modules\myScripts\myScripts.psm1

  3. Created a manifest file with unique GUID in the same folder as the module file:

    C:\Users\\Documents\WindowsPowerShell\Modules\myScripts\myScripts.psd1

  4. Created a folder with all "Public" functions, i.e. the folder will contain all functions, which users are intended to use:

    C:\Users\\Documents\WindowsPowerShell\Modules\myScripts\Public

  5. The Public folder contains the required functions/scripts:

    – C:\Users\\Documents\WindowsPowerShell\Modules\myScripts\Public\Get-Something.ps1
    – C:\Users\\Documents\WindowsPowerShell\Modules\myScripts\Public\Install-Something.ps1

  6. Here is the view of the module file, please note, I have created to be very generic so that I can reuse it if need be:

    If (Test-Path $PSScriptRoot\Public){
    $Public = @( Get-ChildItem -Path $PSScriptRoot\Public\*.ps1 -ErrorAction SilentlyContinue )

    #Dot source the files
    Foreach ($import in $Private)    {
    Try {
    . $import.fullname
    }
    Catch {
    Write-Error -Message "Failed to import function $($import.fullname): $_"
    }
    }
    }
    If (Test-Path $PSScriptRoot\Private){
    $Private = @( Get-ChildItem -Path $PSScriptRoot\Private\*.ps1 -ErrorAction SilentlyContinue )
    Foreach($import in $Public) {
    Try {
    . $import.fullname
    }
    Catch {
    Write-Error -Message "Failed to import function $($import.fullname): $_"
    }
    }
    }
    If (Test-Path $PSScriptRoot\Public){
    Export-ModuleMember -Function $Public.Basename
    }

  7. Here is the view of the manifest file:
    ## Module manifest for module 'myScripts'
    ## Generated by:
    ## Generated on: 12/09/2018
    #
    @{
    # Script module or binary module file associated with this manifest.
    RootModule = 'myScripts.psm1'
    # Version number of this module.
    ModuleVersion = '1.0'
    # ID used to uniquely identify this module
    GUID = "
    # Author of this module
    Author = "
    # Company or vendor of this module
    CompanyName = "
    # Copyright statement for this module
    Copyright = "
    # Description of the functionality provided by this module
    Description = ' PowerShell module'
    # Minimum version of the Windows PowerShell engine required by this module
    PowerShellVersion = '3.0'
    # Functions to export from this module
    FunctionsToExport = '*'
    # Cmdlets to export from this module
    CmdletsToExport = '*'
    # Variables to export from this module
    VariablesToExport = '*'
    # Aliases to export from this module
    AliasesToExport = '*'

    }

If I run the "Import-Module myScritps" command then all modules are imported, but that is not the goal, I would like the system to auto-import the modules every time I open PowerShell. Can you please advise what am I doing wrong?

Thank you!

September 12, 2018 at 12:36 pm

First, you should check out Plaster to aid you in creating modules.

Second, if you have Powershell 3.0 or greater, then a module will be automatically imported if the module is located in one of the default paths listed in $env:PSModulePath. If I had a cmdlet named Get-Something and I referenced it, then Powershell should automatically import the module where Get-Something is contained. Another option is using a Powershell profile

September 12, 2018 at 12:40 pm

FunctionsToExport = '*'

This is your issue. Since the functions are not in the PSM1 directly, Powershell cannot determine what functions are available without executing the module; they will not auto import.

Never use a wildcard in your *ToImport lines. Seriously, never. Even if you can make them work, they are extraordinarily slow to work with, as the comments for the standard PSD1 template (that is generated from New-ModuleManifest) indicate.

Make a habit of updating your PSD1 every time you add another command.

September 12, 2018 at 2:59 pm

Hi @Atis,

I request you to format the code when posting in the forum which makes other to easily understand your code, below link will help you.