Path of a script that calls a function in a module

Hello !

We’re using pretty big PS scripts since years in our high school (stored on a server “[path]\scripts\…”), and are busy to create modules hosting functions that are often common between them (stored on the same server “[path]\modules\…”).
Those scripts are located in separate folders, where we intend to drop specific logs.

I need a way, from each modules, to get the directory path of the script that called them (in order to create/use the right directory where the logs are going to be saved).

I tried different commands/variables in the modules (such as Get-Location, $PSScriptRoot, $MyInvocation.MyCommand.Path, etc …), but none of them were able to return the correct path of the “calling” script. Do you know a way to do this ?

Thank you for your help !

Hi, welcome to the forum :wave:

$MyInvocation.PSCommandPath should do it:

# MyModule.psm1
function Get-CallerPath {
    Write-Host "Path is: $($MyInvocation.PSCommandPath)"
# Test-Script.ps1
Import-Module E:\Temp\MyModule.psm1
# Output
PS G:\Scripts> .\Test-Script.ps1
Path is: G:\Scripts\Test-Script.ps1
1 Like

Matt’s suggestion might be a great approach depending on what you need.

I also wanted to share the -Scope variable on Get-Variable. A scope of ‘1’ means the parent scope. I’ve used this, for example, to have a ‘private’ command that does some stuff, such as setup an object that will be sent to a front end. For example I have this line of code in my private command:

$SourceCommand = (Get-Variable -Name MyInvocation -Scope 1).Value.MyCommand.Name

Obviously this isn’t the right property for what you need but you get the jist I hope. The private function will never be called directly, but I want to capture what the ‘calling’ command name is. I do this through the scope parameter. Then, in a calling function, I’ll call that private function, essentially creating that object, which has info about the calling function using myinvocation variable. There’s no code in the ‘calling’ cmdlet that shows me using it, it’s in the child (private) command and it’s simply looking at the parent scope. This helps me organize my code and keep it cleaner, essentially abstracting code out to the private function.

This might not work for you with your use case but definitely something to play around with as it can be extremely handy.

1 Like

Thanks, Matt. It’s just perfect for what we were trying to achieve :slight_smile:

Thanks also, dotnVo. Your method is very interesting, and I’ll keep it in mind for the rest of our developments.