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.
> Set-Variable -Name strarray -value (’55’,’fiftyfive’,’0x47′) -Scope global -Option ReadOnly
> $strarray
55
fiftyfive
0x47
> $strarray[2] = ‘0x37’
> $strarray
55
fiftyfive
0x37