There's power in defining constants, even in PowerShell. Check out this week's tip.
- By Jeffery Hicks
In Windows PowerShell, we use variables as a place holder for a value of collection of values. Most of the time we can create and define a variable in one step:
PS C:\> $x=100
If we need to change the value of $x all we need to do is assign it a new value:
PS C:\> $x=200
But what if you were relying on the value of $x and didn't want it to be either intentionally or accidently modified? PowerShell offers a few options when defining your variable. You can make a variable read-only or a constant. In either situation, you need to use the New-Variable cmdlet and the -Option parameter:
PS C:\> New-Variable -Name M -Value "Jeff" -Option ReadOnly
PS C:\> $m
PS C:\> $m="Don"
Cannot overwrite variable M because it is read-only or constant.
At line:1 char:3
+ $m <<<< ="Don"
+ CategoryInfo : WriteError: (M:String) , SessionStateUnauthorizedAccessException
+ FullyQualifiedErrorId : VariableNotWritable
When a variable is read-only, you cannot modify its value. As you've seen, PowerShell will complain. However, you are allowed to delete the variable and re-create it:
PS C:\> remove-variable m -force
PS C:\> $m="Don"
PS C:\> $m
You must use -Force to delete the variable. To create a truly protected variable with New-Variable, use a value of Constant with -Option:
PS C:\> $wshell=new-object -com "wscript.shell"
PS C:\> new-variable vbExclaim 48 -Option Constant
PS C:\> $wshell.popup("That didn't go well.",15,"Oops",$vbExclaim)
It's unlikely that I'll overwrite a variable with a name like vbExclaim. But this value will never, ever change so I might as well define it as a constant.
Be aware that if you already have a variable defined with the same name, you need to delete it before you can declare a read-only or constant variable with the New-Variable cmdlet. Since VBScript is full of constants, I find it helpful to define them as such when using VBScript COM objects in Windows PowerShell.
By the way, you can also do the same thing with aliases:
PS C:\> Set-Alias np $env:WinDir\notepad.exe -option ReadOnly
PS C:\> New-Alias slo Select-Object -Option ReadOnly
If you find the need to use constants throughout the day in your PowerShell work, then defining them in your PowerShell profile is a good idea. As to when to make a variable ReadOnly and when a Constant depends on your environment, your script, who will be running it and the consequences if variables don't have the values you are expecting.
Jeffery Hicks is an IT veteran with over 25 years of experience, much of it spent as an IT infrastructure consultant specializing in Microsoft server technologies with an emphasis in automation and efficiency. He is a multi-year recipient of the Microsoft MVP Award in Windows PowerShell. He works today as an independent author, trainer and consultant. Jeff has written for numerous online sites and print publications, is a contributing editor at Petri.com, and a frequent speaker at technology conferences and user groups.