Brekkjern
Brekkjern

Reputation: 31

PowerShell path resolves differently depending on when it's used

I'm working on a PowerShell module and the path resolution in one of my tests is acting really weirdly.

The current folder structure looks like this:

ISPS/
├── ISPS/
│   ├── Private/
│   ├── Public/
│   │   ├── Add-ICDCrawler.ps1
│   │   ├── Get-ICDCrawler.ps1
│   │   ├── New-ICDCrawler.ps1
│   │   └── Remove-ICDCrawler.ps1
│   ├── ISPSCrawler.psd1
│   └── ISPSCrawler.psm1
├── tests/
│   ├── Add-ICDCrawler.tests.ps1
│   ├── Get-ICDCrawler.tests.ps1
│   ├── New-ICDCrawler.tests.ps1
│   └── Remove-ICDCrawler.tests.ps1

The test that's acting weird is Remove-ICDCrawler.tests.ps1. The beginning of the file and relevant part looks like this:

$ModuleRoot = Split-Path $PSScriptRoot -Parent

. $ModuleRoot\ISPS\Public\Get-ICDCrawler.ps1
. $ModuleRoot\ISPS\Public\Remove-ICDCrawler.ps1

When it's run, the dot-sourcing works correctly for the Get-ICDCrawler line, but not for the Remove-ICDCrawler. This is the error message that appears:

. : The term 'D:\Projects\ISPS\ISPS\ISPS\Public\Remove-ICDCrawler.ps1' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At D:\Projects\ISPS\tests\Remove-ICDCrawler.tests.ps1:4 char:3
+ . $ModuleRoot\ISPS\Public\Remove-ICDCrawler.ps1
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

That's straight forward enough. There's one too many ISPS folders in the path. If I remove one of the ISPS folders from line 4 of the test and try again it works perfectly. The problem is that both the Get-ICDCrawler.ps1 and the Remove-ICDCrawler.ps1 files are stored in the same directory and as far as I understand the paths should resolve to the correct directory. As I mentioned, removing ISPS from the path on line 4 works, but it goes against everything I know about PowerShell. Does anyone have any idea why this is happening?

Name                           Value                  
----                           -----                  
PSVersion                      5.1.15063.608          
PSEdition                      Desktop                
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.15063.608         
CLRVersion                     4.0.30319.42000        
WSManStackVersion              3.0                    
PSRemotingProtocolVersion      2.3                    
SerializationVersion           1.1.0.1                

Upvotes: 1

Views: 114

Answers (1)

Brekkjern
Brekkjern

Reputation: 31

I figured it out, so I'm leaving this so people can laugh at it in the future.

The beginning of the Get-ICDCrawler file looks like this:

$ModuleRoot = Split-Path $PSScriptRoot -Parent

. $ModuleRoot\Private\Find-XmlNode.ps1
. $PSScriptRoot\New-ICDCrawler.ps1

So what happens is that I import that file and the $ModuleRoot variable gets changed to be relative to the Get-ICDCrawler.ps1 file. I'll have to make sure the variables are named differently so the namespaces don't collide.

Upvotes: 2

Related Questions