Protect your Variables with ReadOnly and Constant Options

I wrote a post a day to two back about creating an array variable that contained other arrays. I then went on to create additional, easier-to-remember variables, to use as the indexes. Here’s the post if you’d like to read it: http://tommymaynard.com/ql-working-with-an-array-of-arrays-2015/.

I started thinking, what if you create a variable for this easier-to-remember purpose, and then acidentally overwrite it? Well, as assumed, it is no longer going to work as first intended. Here’s a quick example starting back at the array of arrays concept.

PS C:\> Set-Variable -Name TeamWareServers -Value @(('serv01','serv02'),('serv03','serv04','serv05'))
PS C:\> $TeamWareServers
serv01
serv02
serv03
serv04
serv05
PS C:\> Set-Variable -Name f -Value 0 # Front end servers
PS C:\> $f
0
PS C:\> Set-Variable -Name b -Value 1 # Back end servers
PS C:\> $b
1
PS C:\> $TeamWareServers[$f]
serv01
serv02
PS C:\> $TeamWareServers[$b]
serv03
serv04
serv05

Although it’s easier to remember which servers are which, we have the possibility that our variables, $f and $b, could easily be overwritten. Here’s an example of overwriting the variables’ values and then not being able to use them as we did in the last example. I added an extra space after the results, of which there were none, so it’s easy to tell that these variable no longer work.

PS C:\> $f = 20
PS C:\> $b = 'newvalue'
PS C:\> $TeamWareServers[$f]
PS C:\>
PS C:\> $TeamWareServers[$b]
PS C:\>

So, how can we better protect our variables? There’s two ways we’ll discuss: ReadOnly and Constant. These two options will protect our variables from being assigned any new value(s). Take a look at this example where we’ll reset our $f and $b variables back to their original values.

PS C:\> Set-Variable -Name f -Value 0 -Option ReadOnly
PS C:\> $f
0
PS C:\> Set-Variable -Name b -Value 1 -Option Constant
Set-Variable : Existing variable b cannot be made constant. Variables can be made constant only at creation time.
At line:1 char:1
+ Set-Variable -Name b -Value 1 -Option Constant
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (b:String) [Set-Variable], SessionStateUnauthorizedAccessException
    + FullyQualifiedErrorId : VariableCannotBeMadeConstant,Microsoft.PowerShell.Commands.SetVariableCommand

In the example above, we assigned a new value to our $f variable and made it ReadOnly using the -Option parameter. When we tried to modify the $b variable to make it a Constant, we received an error. This is because we don’t have the ability to make an existing variable a Constant. In the next example, below, we’ll remove the $b variable and then recreate it with the Constant option. Keep in mind that Set-Variable will work like New-Variable, if the variable doesn’t already exist.

PS C:\> Remove-Variable -Name b
PS C:\> Set-Variable -Name b -Value 1 -Option Constant
PS C:\> $b
1

Now let’s try what we did earlier and assign new values to these variables. You’ll soon see that when the variable’s option is set to Read-Only or Constant, that we’re not able to change their values.

PS C:\> $f = 20
Cannot overwrite variable f because it is read-only or constant.
At line:1 char:1
+ $f = 20
+ ~~~~~~~
    + CategoryInfo          : WriteError: (f:String) [], SessionStateUnauthorizedAccessException
    + FullyQualifiedErrorId : VariableNotWritable

PS C:\> $b = 'newvalue'
Cannot overwrite variable b because it is read-only or constant.
At line:1 char:1
+ $b = 'newvalue'
+ ~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (b:String) [], SessionStateUnauthorizedAccessException
    + FullyQualifiedErrorId : VariableNotWritable

If you’re anything like me, then you might be wondering what the difference is between ReadOnly and Constant. We’ll let the next example help explain.

PS C:\> Remove-Variable -Name f
Remove-Variable : Cannot remove variable f because it is constant or read-only. If the variable is read-only, try the
operation again specifying the Force option.
At line:1 char:1
+ Remove-Variable -Name f
+ ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (f:String) [Remove-Variable], SessionStateUnauthorizedAccessException
    + FullyQualifiedErrorId : VariableNotRemovable,Microsoft.PowerShell.Commands.RemoveVariableCommand

PS C:\> Remove-Variable -Name f -Force # This works.
PS C:\>
PS C:\> Remove-Variable -Name b
Remove-Variable : Cannot remove variable b because it is constant or read-only. If the variable is read-only, try the
operation again specifying the Force option.
At line:1 char:1
+ Remove-Variable -Name b
+ ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (b:String) [Remove-Variable], SessionStateUnauthorizedAccessException
    + FullyQualifiedErrorId : VariableNotRemovable,Microsoft.PowerShell.Commands.RemoveVariableCommand

PS C:\> Remove-Variable -Name b -Force # This doesn't work.
Remove-Variable : Cannot remove variable b because it is constant or read-only. If the variable is read-only, try the
operation again specifying the Force option.
At line:1 char:1
+ Remove-Variable -Name b -Force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (b:String) [Remove-Variable], SessionStateUnauthorizedAccessException
    + FullyQualifiedErrorId : VariableNotRemovable,Microsoft.PowerShell.Commands.RemoveVariableCommand

When a variable is ReadOnly, the variable can be removed. This does, however, require the use of the -Force parameter. Consider that a safety net. The difference here, is that when a variable is a Constant, it cannot be removed, even with the use of the -Force parameter. If you want to remove a user-defined Constant variable, you’re going to have to end your PowerShell console and start another one.

Keep these options in mind if you ever want to protect the value(s) in your variables. While we’re at it, we probably should have made the array (of arrays) variable, $TeamWareServers, ReadOnly or Constant, too.

One thought on “Protect your Variables with ReadOnly and Constant Options

  1. jim

    > Set-Variable -Name strarray -value (’55’,’fiftyfive’,’0x47′) -Scope global -Option ReadOnly

    > $strarray
    55
    fiftyfive
    0x47

    > $strarray[2] = ‘0x37’

    > $strarray
    55
    fiftyfive
    0x37

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *