0

In Windows PowerShell (version 5.1.19041.4894) what should I do to have modules loaded? This is in the $Env:PSModulePath: D:\Users\theking2\OneDrive\Documents\WindowsPowerShell\Modules;.....

The module I'm expeciting to load is in D:\Users\theking2\OneDrive\Documents\WindowsPowerShell\Modules\WatchFile and is called WatchFile.psm1 and starts with

# Define the file path to monitor
function Watch-File {
    [cmdletbinding()]
    Param (
        [string]
        $Path
    )

The command Watch-File however is not recognized as the name of a cmdlet, function, script file, or operable program.

5
  • It should work. Does import-module give an error message? Commented Sep 29, 2024 at 14:49
  • @js2010 Import-Module does not give an error. Commented Sep 29, 2024 at 15:21
  • Running a script from TaskScheduler does work. PowerShell "Watch-File c:\wamp\logs\php_error.log" does start watching that file. Commented Sep 29, 2024 at 15:27
  • 1
    None of the answers are true. It works for me just like you did. Maybe the environment variable isn't properly set. If the psm1 file has a different name than the folder it won't work either. Commented Sep 29, 2024 at 15:38
  • 1
    My answer was wrong,Export-module exports all functions if not specified..based on given code, your script file should work...What happens when you import module explicitly.. learn.microsoft.com/en-us/powershell/module/… Commented Sep 29, 2024 at 16:40

1 Answer 1

2

tl;dr

  • Your module should autoload, based on the information given.

  • The next section details the prerequisites for autoloading and suggests that your module be given a manifest.


For a module to autoload, the following prerequisites must be met:

  • The module must be placed in a directory that contains a *.psd1 file (module manifest) or *.psm1 file or both (a *.psm1 file alone is not recommended; see next section).

  • The directory name must match the base file name of the *.psd1 file, if present, or the *.psm1 file otherwise, such as, in your case, a WatchFile.psm1 file being located in a WatchFile directory.

    • Alternatively, for side-by-side installations of modules (multiple versions), an intermediate directory with a version number may be present, e.g., the module files may be placed in directory WatchFiles\2.0.3
  • The directory must be a child directory of one of the directories listed in the $env:PSModulePath environment variable.

    • The directories must be separated with ; on Windows, and : on Unix-like platforms.
  • If a *.psd1 file is present, it must be valid module and not contain syntax errors.

  • If only a *.psm1 file is present, it must not contain syntax errors.

    • To rule out syntax errors, try to import the *.psm1 file directly, using Import-Module

    • If an associated, valid *.psd1 is present, module discovery still works and an attempt at autoloading is made, which fails; the error message recommends using an Import-Module call to surface error details.


Your module is unusual in that when you author a module that stores a *.psm1 inside a directory with the same base name (WatchFile.psm1 inside a WatchFile directory), you typically also provide a *.psd1 file, i.e. a module manifest, which is imported first and allows control over what the associated *.psm1 file ultimately exports, via *ToExport entries.

While module autoloading does not require a manifest file in order to discover a module, it is recommended for better performance (if a manifest is present, PowerShell need only parse it to determine what elements (functions/cmdlets, aliases, and possibly also variables) exports.

In the absence of a manifest file, it is the *.psm1 file alone that controls what to export:

  • By default, all function and alias definitions are exported.
  • If needed, you can modify this default behavior with a an Export-ModuleMember call, such as to also export variables (which is rare) or to export only a subset of the functions and aliases.

In the presence of a manifest file, the latter further constrains what the *.psm1 file exports, and it is only the constrained exports that an importer sees:

  • So as not to negate the module-discovery performance benefits of using a module manifest, all *ToExport entries should either list the exported elements explicitly instead of using wildcard expressions (e.g., FunctionsToExport = @('Watch-File)), or - if there are no elements of a given type to export - should define the relevant *ToExport entry with the empty array (e.g, VariablesToExport = @())

  • To provide a manifest for you module, place a WatchFile.psd1 module manifest in your WatchFile directory, make it reference WatchFile.psm1 as its root module, and make its FunctionsToExport entry list (at least) Watch-File; here's how you can generate such a manifest using New-ModuleManifest:

    New-ModuleManifest ./WatchFile.psd1 -RootModule WatchFile.psm1 -FunctionsToExport Watch-File
    
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.