The properties of the PSVariable object allow you to store a Description in your variable. In addition, you can configure the Visibility, Options, and Attributes for variables.
Latest posts by Michael Pietroforte (see all)

In my last post, where I demonstrated how you can use the Get-Variable cmdlet to debug your PowerShell scripts, I mentioned the PSVariable object. Today, I will take a closer look at this important PowerShell object, and we’ll discover what things we can do with it.

The PSVariable object ^

In most cases, when you interact with a variable, you will precede the variable name with the dollar sign, which tells the shell to read the variable’s value. However, the value is just one of several properties of the variable object. In the following example, we display all the properties of a variable object:

$myVariable = "Variables are objects."
Get-Variable myVariable | Select *

In the second command, we select all of the variable’s properties, including the hidden ones (properties that are not displayed by default).

Displaying all properties of the PSVariable object

Displaying all properties of a PSVariable object

Note that other variable object types exist. You can use the following command to get a list of variable types available in the variables of your current scope:

Get-Variable | Get-Member | Select TypeName -Unique

Variable descriptions ^

It won’t surprise you that the variable Name is another object property. The Description property can be useful if you want to document the purpose of a variable. The advantage over documenting in comments in your script is that you can easily see the descriptions of all variables that you list.

To store a Description in a variable, you use the Set-Variable cmdlet:

Set-Variable -Name myVariable -Description "My variable description"

You can also assign a Description when you create the variable with the New-Variable cmdlet:

New-Variable -Name myVariable -Value "Variables are objects" -Description "My variable description"

To view the Description of a particular variable, you can use the Get-Variable cmdlet, as in the first example in this post. This works, too:

$myVariable = "Describe your variables"
$myVariableObject = Get-Variable myVariable
$myVariableObject.Description = "My variable description"

Setting a description for a variable

Setting a description for a variable

To display the variables with their descriptions in your current PowerShell session, you can run this command:

Get-Variable | Select Name,Value,Description

The command above displays all the variables that you created on your console in addition to the automatic variables that PowerShell has set on your host. This gives you a quick overview of the purpose of each of the automatic variables.

To display only your own variables with their descriptions, you have to follow the instructions in my previous post and create the cmpv function in your profile. You can then display all your own variables, along with their description, this way:

cpmv | Select Name,Value,Description

Variable visibility ^

The Visibility property of a PowerShell variable can have the values Public or Private. Public is the default. Don’t confuse this property with the Private scope. The Visibility property allows a developer of a PowerShell module to hide variables. If you import a module with variables where Visibility is set to Private, you can’t view or change the variable on the console even if it is in the Global scope. If you try to access a Private variable, PowerShell will throw an error message: Cannot access the variable '$myPrivateVariable' because it is a private variable.

New-Variable -Name myPrivateVariable -Value "This is really private." -Visibility "Private" 
Get-Variable myPrivateVariable

Error message when trying to access a Private variable

Error message when trying to access a Private variable

Variable options ^

Another useful variable property is Options. Five valid values exist for this property: AllScope, Private, Constant, ReadOnly, and None. None is the default configuration.

I already discussed AllScope in my post about variable scopes. A variable where this option is set is available in all new child scopes. Private does the opposite; the variable will only be available on the current (Local) scope. This has the same effect as if you declare the variable as Private when you initialize it:

$Private:myPrivateVariable = "I value my privacy."
New-Variable -Name myPrivateVariable -Value "I value my privacy." -Option Private  
Get-Variable myPrivateVariable | Select *

Different ways to set a variable as Private

Different ways to set a variable as Private

These two commands accomplish the same thing. If you run one after the other, PowerShell will complain that you keep repeating yourself.

The Options properties Constant and ReadOnly have a similar effect: you can protect a variable from being overwritten with a new value. Protecting your variable with Constant is just a bit more reliable. You can delete a ReadOnly variable, and you may also override it by using the -Force parameter. A Constant variable cannot be changed at all, and you can only destroy it by ending your PowerShell session.

New-Variable -Name myReadOnlyVariable -Value "Please don't change me!" -Option ReadOnly
$myReadOnlyVariable = "I want to change you."
Set-Variable -Name myReadOnlyVariable -Value "I really need to change you." -Force
Remove-Variable myReadOnlyVariable -Force
Get-Variable myReadOnlyVariable

Changing a ReadOnly Variable

Changing a ReadOnly Variable

Note that you cannot change the Options property of a ReadOnly variable. You first have to delete and then re-create it. The following examples demonstrate that Constant variables are truly constant:

New-Variable -Name Pi -Value 3.14 -Option Constant
Set-Variable -Name Pi -Value 3.141 -Force
Remove-Variable Pi -Force

Trying to change and delete a Constant variable

Trying to change and delete a Constant variable

You are probably wondering why you would want to use ReadOnly and Constant variables if it causes so much trouble to change them. In programming languages that have to be compiled, the declaration of constants allows for compilation optimization; this is of no help in PowerShell because it is an interpreted language.

However, you can see ReadOnly and Constant variables as additional variable types. Type safety improves the reliability of your scripts. If you know that the value of a variable should not be changed in the entire script, you can set it to ReadOnly; if you are sure that a variable must not be changed, you can you set it to Constant. It is often better to allow a script to terminate with an error message rather than move ahead with the wrong variable values. Furthermore, if you work on a large project with other PowerShell developers, clarifying how a variable should be treated will improve the readability of your code.

ReadOnly and Constant variables can also be helpful when you are working at a PowerShell prompt. For instance, if you defined variables in your profile to save yourself from typing complex arguments, you might want to prevent Global variables in a script from accidentally overriding your variables.

Variable attributes ^

Variable attributes allow you to restrict the value of a variable. In a way, this enables you to create your own variable types. For example, you can restrict the range of an integer variable or limit the length of a string. The purpose is to make your script more reliable. This feature also allows you to validate user inputs. Of course, you can achieve the same results by validating the contents of a variable in your script. However, if you store the restrictions in the variable’s Attributes property, you ensure that its value will always meet your requirements.

Variable attributes are saved as an array in the PSVariable object, which enables you to assign multiple attributes to a variable. A variable attribute is an object by itself that you can create with the New-Object cmdlet. Object type names of variable attributes start with “System.Management.Automation.” The table below lists the abbreviated object type names that you can use to validate variables:

Type Name (Abbreviated)Purpose
ValidateRangeAttributeNumber range
ValidateSetAttributeParticular values
ValidatePatternAttributeRegular expression
ValidateNotNullOrEmptyAttributeNot zero or empty
ValidateNotNullAttributeNot zero

So, for instance, the complete type name for configuring a number range is System.Management.Automation.ValidateRangeAttribute. In the following example, we restrict the values of an integer to the range 1-9:

[Int]$Number = Read-Host "Enter a number in the range 1-9"
$Attribute = New-Object System.Management.Automation.ValidateRangeAttribute -ArgumentList 1,9
(Get-Variable Number).Attributes.Add($Attribute)

Restricting a number to the range 1-9

Restricting a number to the range 1-9

In the above example, I entered the number 10, and PowerShell answered with an error message because the number is not in the specified range. If you want to prevent the error message, this little script shows how:

Function ValidateAnswer ($Answer)
     $Attribute = New-Object System.Management.Automation.ValidateSetAttribute -ArgumentList Yes,No
     (Get-Variable Answer).Attributes.Add($Attribute)    
Function LetsTry 
         $Answer = Read-Host "Do you want to continue, yes or no?"
         ValidateAnswer($Answer) -Errocation Stop
         Write-Host "Thank you! Good choice!"
         Write-Host "Come on, I asked yes or no!"

This script asks for user input and only accepts “yes” or “no” as an answer. If you enter anything else, the script will ask again. Admittedly, easier ways exist to accomplish this task, but I think you now have an idea of how you can use variable attributes.

 Validating user input

Validating user input

This concludes my variable series. I didn’t discuss everything that can be said about PowerShell variables, but I think you now know the most features.

Articles in series

The PowerShell variable

  1. Alex 3 years ago

    Hi Michael,

    i found this article and its very helpful. Im new in powershell, so im still learning. Maybe you can answer me a question about the argumentlist. Im trying to put the "yes,no" list into a variable. How can I do this?



  2. Tomer 3 years ago


    Firstly, thanks. Awesome series!!

    I do have a questions though.

    Is there a way to declare a global variable with Constant option without using the CMDlet?

    In other words... is there a way to give this variable the option Constant:

    $global:VAR_NAME = <value>

    Without needing the entire New-Variable -Option Constant

Leave a reply

Please enclose code in pre tags

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


© 4sysops 2006 - 2021


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account