PowerShell - referencing files relative to the currently executing script
I often have the situation that that I want to do a relative reference to a script file from another script file. This works ok if we execute the referencing script file from its current location, but what if that script is referenced as well. Ok, a bit vague, an example:
Folder c:\test contains script X.ps1
Folder c:\test\sub contains script Y.ps1
Folder c:\test\sub contains script Z.ps1
The initially executing script is: C:\test\X.ps1
The scripts are defined as follows:
C:\test\X.ps1:
./sub/Y.ps1
Write-Host "X"
C:\test\sub\Y.ps1:
./Z.ps1 # this one not found, because the current folder is c:\test, not c:\test\sub
Write-Host "Y"
C:\test\sub\Z.ps1:
Write-Host "Z"
I have this problem if Y.ps1 and Z.ps1 are part of a utility library, and X.ps1 is one of the calling scripts. A good example is the psexpect library from www.codeplex.com where I had exactly this problem.
The PowerShell guy (/\/\o\/\/) came to the rescue with the following solution:
Split-Path -Path $MyInvocation.MyCommand.Path -Parent
We can rewrite our scripts as follows:
C:\test\X.ps1:
$executingScriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
Write-Host "Script X: script folder=$executingScriptDirectory"
& "$executingScriptDirectory/sub/Y.ps1"
Write-Host "X"
C:\test\sub\Y.ps1:
$executingScriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
Write-Host "Script Y: script folder=$executingScriptDirectory"
& "$executingScriptDirectory/Z.ps1"
Write-Host "Y"
C:\test\sub\Z.ps1:
Write-Host "Z"
- The start script C:\test\X.ps1 can now be executed from any location.
- The library script C:\test\sub\Y.ps1 can be utilized by any script.
Note that this code must be executed in the body of the script, and not from within a function!!
The one strange thing that puzzles me now is why PowerShell Analyzer gives the following exception:
--------------------------------------------------------------------------------
POWERSHELL EXCEPTION
EXCEPTION TYPE:System.Management.Automation.CmdletInvocationException
MESSAGE:Cannot find drive. A drive with name '$executingScriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
Write-Host "Script X' does not exist.
POSITION:
At line:1 char:39
+ $executingScriptDirectory = Split-Path <<<< -Path $MyInvocation.MyCommand.Definition -Parent
--------------------------------------------------------------------------------
So many words to explain a problem and solve an issue that was so easy in cmd.exe, ~dp0 did the job!