0

In my PowerShell script Main.ps1 I need to access a variable $script_name or $script_path to return the name and path of this running script.

Elsewhere, I have seen something like this:

$fullPathIncFileName = $MyInvocation.MyCommand.Definition
$currentScriptName = $MyInvocation.MyCommand.Name
$currentExecutingPath = $fullPathIncFileName.TrimEnd("\"+$currentScriptName)

This works well. But does it mean I need to place this much text in each and every script where I want to automatically get the current script's name and path?

I thought about placing those 3 lines in another script (named Variables.ps1 and dot sourcing it anywhere else it is needed. Like so:

# Main.ps1
. ".\Variables.ps1"

Write-Host $currentScriptName

Unfortunately this still prints "Variables.ps1"

Placing the 3 lines of code in the current profile script is even worse. Of course, the profile script variables are run and fossilized as the console is launched, and something like this: $current_time = Get-Date or $var = [ANY WINDOWS ENVIRONMENT VARIABLE] when placed in the profile, will always return the time the console was launched, even when the calling script is running one week later!

So my question is: How can I most concisely re-use such a variable (with dynamic value) in my scripts by declaring it elsewhere, such that when called, it "determines" its value at the point of being called.

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
Ifedi Okonkwo
  • 3,406
  • 4
  • 33
  • 45
  • 1
    Have you seen this? http://stackoverflow.com/a/5466355 – Zombo Nov 20 '14 at 09:04
  • @StevenPenny. I appreciate your input. I'd actually seen that before, tried `$PSScriptRoot` and got blank ON THE CONSOLE. But on your counsel, I went back to check, then realized what I'd misunderstood: `$PSScriptRoot` can only work WITHIN A SCRIPT, apart from being also a version 3.0 "child-item". – Ifedi Okonkwo Nov 20 '14 at 17:26

1 Answers1

1

For dynamically updated values you need a function:

PS C:\> Get-Content .\source.ps1
function Get-Invocation {
  "Running: {0}" -f $script:MyInvocation.MyCommand.Name
}
PS C:\> Get-Content .\run.ps1
. .\source.ps1
Get-Invocation
PS C:\> .\run.ps1
Running: run.ps1

or at least a scriptblock that you invoke in the script:

PS C:\> Get-Content .\source.ps1
$invocation = {
  "Running: {0}" -f $script:MyInvocation.MyCommand.Name
}
PS C:\> Get-Content .\run.ps1
. .\source.ps1
Invoke-Command -ScriptBlock $invocation
PS C:\> .\run.ps1
Running: run.ps1
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
  • Thanks @Ansgar for usefully pointing me in the right direction: Use a function! Now I've been able to do this: `function Get-ScriptPath { $fullpath = $Script:MyInvocation.MyCommand.Definition; $name = $Script:MyInvocation.MyCommand.Name; $dir = $fullpath.TrimEnd("\"+$name); return $dir; }` in my Current Profile such that I can call `Get-ScriptPath` from any currently running script. God bless ya! – Ifedi Okonkwo Nov 20 '14 at 17:20