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