Powershell: `using module` statement with a relative path not treated as relative to the location of the enclosing script when forward slashes are used

Created on 1 Aug 2018  路  9Comments  路  Source: PowerShell/PowerShell

_Update_: @PetSerAl has determined that the problem only surfaces with / as the path separator, not \.

Needless to say, / should be supported, because it is the native paths separator on Unix-like platforms and since it must be used for filesystem paths that work across all platforms.

Steps to reproduce

Set-Location /tmp # change to tmp dir. (make sure it exists)

# Create a module
'function Get-Foo { "hi from t.psm1" }' > t.psm1

# Create a script that references the module
# with `using module` and a *relative path* with */*
# Using '.\t.psm1` would *not* surface the problem.
'using module ./t.psm1; Get-Foo' > t.ps1

# Invoke the script from the current location:
./t.ps1

# Change to a different location and invoke again.
Set-Location /; /tmp/t.ps1

Expected behavior

hi from t.psm1
hi from t.psm1

Actual behavior

hi from t.psm1
/tmp/t.ps1 : The specified module '/t.psm1' was not loaded because no valid module file was found in any module directory.
# ...

That is, invoking the script from a location other than the one where it resides breaks the using module statement, because the relative path is seemingly interpreted relative to the _current_ location rather than the script's.

As an aside: Fixing this also requires attention to symlinks: if the enclosing script is a symlink, its ultimate _target_'s location should serve as the reference point.

Environment data

PowerShell Core v6.1.0-preview.4 on macOS 10.13.6
PowerShell Core v6.1.0-preview.4 on Ubuntu 16.04.4 LTS
PowerShell Core v6.1.0-preview.4 on Microsoft Windows 10 Pro (64-bit; Version 1803, OS Build: 17134.165)
Windows PowerShell v5.1.17134.165 on Microsoft Windows 10 Pro (64-bit; Version 1803, OS Build: 17134.165)
Issue-Bug Resolution-Fixed Up-for-Grabs WG-Engine

Most helpful comment

(I general I tend to use / since Windows accepts both and *nix has a preference, especially when passing into .NET APIs)

All 9 comments

using module ./t.psm1; -> using module .\t.psm1;

It seems PowerShell dislikes /.

Thanks @PetSerAl - it hadn't even occurred to me to try with \ (OP updated); should be an easy fix then.

@iSazonov: Thanks for labeling, but PowerShell not treating / the same as \ in this context is a bug, not an enhancement.

Wow @mklement0 I just hit this, and like you said I had no idea using \ would be a workaround. You saved me on that! Hopefully I can fix this at some point

(I general I tend to use / since Windows accepts both and *nix has a preference, especially when passing into .NET APIs)

Any updates on this?

I had a quick look (not an exhaustive one) and it seems like this might be a fairly simple fix:

https://github.com/PowerShell/PowerShell/blob/b7cb335f03fe2992d0cbd61699de9d9aafa1d7c1/src/System.Management.Automation/engine/parser/SymbolResolver.cs#L493-L509

Line 502 here incorrectly assumes that a path must contain \ to be a valid path.

Best fix would be using a method from LocationGlobber - I guess we have already such one.

:tada:This issue was addressed in #12492, which has now been successfully released as v7.1.0-preview.3.:tada:

Handy links:

:tada:v7.1.0-preview.3 has been released which incorporates this pull request.:tada:

Handy links:

Was this page helpful?
0 / 5 - 0 ratings