Search code examples
powershell

PowerShell "using module ./" is forcing me to use the c:/users/{username} folder


I've got 2 powershell files, one ps1 the other psm1. The code is simple.

  • personClass.psm1
class Person {
    [String]$Name
    [int]$Age

    # Constructor.
    Person([String]$Name, [int]$Age) {
        $this.Name = $Name
        $this.Age = $Age
    }

    [String]GreetPerson([String]$PreferredGreeting) {
        if($PreferredGreeting -eq "" -or $null -eq $PreferredGreeting) {
            $PreferredGreeting = "Hello"
        }
        return "$PreferredGreeting, $($this.Name). I can't believe you're $($this.Age) years old."
    }

    [void]HaveBirthday() {
        $this.Age++
    }
}
  • File test.ps1
using module ./personClass.psm1

$me = [Person]::new('Garrett', 9000)
Write-Output $me.GreetPerson('Salutations')
$me.HaveBirthday()
Write-Output $me.GreetPerson('Salutations')

When I run this code, I get the error The specified module 'C:\Users\jreddy\personClass.psm1' was not loaded because no valid module file was found in any module directory.

Why is this looking in that directory? Shouldn't the ./ look in the executing directory? I've tried a few things and nothing works. If I move my psm1 file to the user directory it works, but that is not an option.


Solution

  • Santiago has provided the crucial pointers in comments, but let me elaborate:

    Shouldn't the ./ look in the executing directory?

    If by executing directory you mean the directory in which the running script is located (as opposed to the current aka working directory), then, yes.
    In other words: a relative path in a using module statement is interpreted as relative to the directory in which the script at hand is located.

    Unfortunately, a bug in Windows PowerShell (the legacy, ships-with-Windows edition of PowerShell whose latest and last version is v5.1.x) requires the use of .\ (note the backslash) for this to work - ./ (forward slash) does not work there.

    This bug has been fixed in PowerShell (Core) 7, so you're free to use ./ and .\ interchangeably there, as is generally supported in paths in PowerShell.[1]


    [1] The bug also affected versions up to v7.0.x of PowerShell (Core) 7, which are now obsolete, however.