How to create global constant variables in PowerShell

Viewed 10233
## My try to create a global constant 
Set-Variable -Name c -Value "x" -Option Constant -Scope Global -Force

Write-Host $c  ## -> x
$c = "y"       ## -> WriteError: (C:String) [], SessionStateUnauthorizedAccessException 
               ## -> VariableNotWritable
Write-Host $c  ## -> x

function test {
    Write-Host $c  ## -> x
    $c = "xxxx"
    Write-Host $c  ## -> xxxx
}

test 

My variable $c is global accessible, but not constant in all cases. Try to change the value inside the function test() and PowerShell allows a change of value.

Is there a way to create a true global constant variable?

Background:

I have a main script. The main script loads a few modules. Through all the modules and in the main script I need some fixed file and registry paths. So I want to declare these paths as global constants.

2 Answers

The global variable $c remains constant, but with the assignment $c = "xxxx" another local variable $c is defined that takes the new value and masks the global variable in the local context.

Demonstration:

PS C:\> Set-Variable -Name c -Value "x" -Option Constant -Scope Global -Force
PS C:\> function test {
>>     Get-Variable -Name c -Scope Global
>>     Get-Variable -Name c -Scope Local
>>     $c = "xxxx"
>>     Get-Variable -Name c -Scope Global
>>     Get-Variable -Name c -Scope Local
>> }
>>
PS C:\> test

Name                           Value
----                           -----
c                              x
Get-Variable : Cannot find a variable with the name 'c'.
At line:3 char:5
+     Get-Variable -Name c -Scope Local
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (c:String) [Get-Variable], ItemNotFoundException
    + FullyQualifiedErrorId : VariableNotFound,Microsoft.PowerShell.Commands.GetVariableCommand

c                              x
c                              xxxx

The first Get-Variable -Name c -Scope Local call fails, because there is no local variable $c defined yet.

The issue can be avoided by prefixing the variable/constant with the correct scope:

PS C:\> Set-Variable -Name c -Value "x" -Option Constant -Scope Global -Force
PS C:\> function test {
>>     $global:c
>>     $global:c = "xxxx"
>>     $global:c
>> }
>>
PS C:\> test
x
Cannot overwrite variable c because it is read-only or constant.
At line:3 char:5
+     $global:c = "xxxx"
+     ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (c:String) [], SessionStateUnauthorizedAccessException
    + FullyQualifiedErrorId : VariableNotWritable

x

or by defining the constant for all scopes:

PS C:\> Set-Variable -Name c -Value "x" -Option Constant, AllScope -Force
PS C:\> function test {
>>     $c
>>     $c = "xxxx"
>>     $c
>> }
>>
PS C:\> test
x
Cannot overwrite variable c because it is read-only or constant.
At line:3 char:5
+     $c = "xxxx"
+     ~~~~~~~~~~~
    + CategoryInfo          : WriteError: (c:String) [], SessionStateUnauthorizedAccessException
    + FullyQualifiedErrorId : VariableNotWritable

x

For a complete answer:

#________________________________________________
# Example1, without prefix
#________________________________________________
$c="val1"

# Print output c variable
$c

function test
{
    $c="val2"
}

test

# Print output c variable (c not change)
$c

#________________________________________________

# Example2, with prefix global
#________________________________________________
$global:c="val1"

# Print output c variable
$global:c

function test2
{
    $global:c="val2"
}

test2

# Print output c variable (c change)
$global:c

#________________________________________________

# Example3, with prefix script
#________________________________________________
$script:c="val1"

# Print output c variable
$script:c

function test3
{
    $script:c="val2"
}

test3

# Print output c variable (c change)
$script:c

#________________________________________________

# Example 4, with get and set variable --> see answer of Ansgar Wiechers
#________________________________________________

NB: Difference of global and script is a scope question. For more details, see here.

Related