1

So I have a personal project I'm working on where I want to set the value of $Name to the name of the script without the path or file extensions. I thought I could do this as a global variable since it needs to called a few times.

I've used the set-variable command and used $global:Name but nothing seems to work when I call the variable in the function. I've also used other variable names such as "foo" and it still wasn't working. Here are some example code snippets:

Set-Variable -name Name -value [IO.Path]::GetFileNameWithoutExtension($MyInvocation.ScriptName) -scope global
function test {
    $Name
}
test
Pause

I've also tried:

Set-Variable -name Name -value [IO.Path]::GetFileNameWithoutExtension($MyInvocation.ScriptName) -scope global
function test {
    $global:Name
}
test
Pause

And:

$global:Name = [IO.Path]::GetFileNameWithoutExtension($MyInvocation.ScriptName)

function test {
    $Name
}
test
Pause

And:

$global:Name = [IO.Path]::GetFileNameWithoutExtension($MyInvocation.ScriptName)
function test {
    $global:Name
}
test
Pause

And:

$script:Name = [IO.Path]::GetFileNameWithoutExtension($MyInvocation.ScriptName)
function test {
    $script:Name
}
test
Pause

And:

$script:Name = [IO.Path]::GetFileNameWithoutExtension($MyInvocation.ScriptName)
function test {
    $Name
}
test
Pause

I was expecting the name of the script to appear but it just returns null. Anyone know why this is happening? Any advice is much appreciated!

3
  • 1
    my understanding is that once you define a $Global: variable, you must always refer to it as such ... otherwise you will risk creating a new variable in the current scope. Commented Jul 17, 2019 at 22:59
  • 1
    Always using $global: is definitely the most robust way to refer to a global variable; specifically, it is assigning to a variable of the same name without the $global: scope in a non-global scope that creates a local variable that shadows the global one - see stackoverflow.com/a/54317129/45375 for the full story. Commented Jul 18, 2019 at 2:11
  • 1
    @Excallypurr, zdan's answer solves your problem, but as an aside: using Set-Variable means that argument-mode parsing is applied, so to use an expression such as [IO.Path]::GetFileNameWithoutExtension($MyInvocation.ScriptName) you need to enclose it in (...) - see stackoverflow.com/a/41254359/45375 Commented Jul 18, 2019 at 2:14

1 Answer 1

2

$MyInvocation does not provide information about the current script. It tells you about who called the script. As per the help:

Unlike the $PSScriptRoot and $PSCommandPath automatic variables, the PSScriptRoot and PSCommandPath properties of the $MyInvocation automatic variable contain information about the invoker or calling script, not the current script.

So what you want to use is $PSCommandPath, like this:

$global:Name = [IO.Path]::GetFileNameWithoutExtension($PSCommandPath)
function test {
    $Name
}
test
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.