Tag Archives: variable

PowerShell Variable Description Property

I don’t remember who mentioned it, but someone in the PowerShell community recently tweeted that they had been working with PowerShell for 10 years and had just learned something new. It wasn’t new to me, but I’m sure there are things out there I’ve yet to encounter. I sure hope so, anyway!

This individual didn’t realize that variables in PowerShell have descriptions. Did you know that!? Here are a few examples of different uses. Eventually, we’ll get to the description property, as well as all the properties you get every time you create a variable in PowerShell.

[PS7.1.5][C:\] $Variable = 'This is a string variable.'
[PS7.1.5][C:\]  $Variable
This is a string variable.
[PS7.1.5][C:\]
[PS7.1.5][C:\] Get-Variable -Name Variable -ValueOnly
This is a string variable.
[PS7.1.5][C:\]
[PS7.1.5][C:\] (Get-Variable -Name Variable).Value
This is a string variable.
[PS7.1.5][C:\]
[PS7.1.5][C:\] Get-Variable -Name Variable

Name                           Value
----                           -----
Variable                       This is a string variable.

[PS7.1.5][C:\] Get-Variable -Name Variable | Select-Object -Property *

PSPath        : Microsoft.PowerShell.Core\Variable::Variable
PSDrive       : Variable
PSProvider    : Microsoft.PowerShell.Core\Variable
PSIsContainer : False
Name          : Variable
Description   :
Value         : This is a string variable.
Visibility    : Public
Module        :
ModuleName    :
Options       : None
Attributes    : {}

[PS7.1.5][C:\]  

There it is… Description. Let’s add one and then return it!

[PS7.1.5][C:\] Set-Variable -Name Variable -Description 'This is the description property of a string variable.'
[PS7.1.5][C:\] (Get-Variable -Name Variable).Description
This is the description property of a string variable.

If you didn’t know this either, then just maybe this is exciting for you, too! I liked it when I first found it. I will link an old post below that I wrote about variable descriptions the first time around. It may be much of what was presented here already. There’s another post I wish I could find, but I think it was posted on another website and it has since been lost. Somebody on some forum wanted to know the last value that a variable contained and so I wrote a post about storing the variable’s previous value in the description property each time the variable was updated to something new. That’s was fun, and unique!

Give  your Variable a Description

Create Function from Variable Value I

If you were here Wednesday, then perhaps you already read Get the Total Parameter Count. If not, I’ll quickly tell you about it. I wanted to know how many parameters a function had whether or not those parameters were used when the function was invoked. I did this by using Get-Help against the function, from within the function. Yeah, I thought it was cleaver too, but the best part, it gave me the results I was after. If a function had three parameters, it was indicated in the function’s output. Same goes for when it had two parameters, but of course in that instance, it indicated two.

In going along with that post I had an idea. I wanted to create a way to dynamically create a function with a random number of parameters between one and ten. Then, I could prove my code was working. Sure, I could’ve used Pester, but I was after making this work — this whole, create a function with a random number of parameters thing. I needed to figure out how to get the code for a function, stored inside a variable, into an actual PowerShell function. That might’ve been confusing, but the example code in this post will probably prove helpful.

I’ll show you what I started experimenting with for discovery purposes, and then we’ll jump into the code that actually creates my function with a random number of parameters in a soon to be released second part to this post.

First, we’ll start with a here-string variable assignment. Using a here-string allows us to include multiple line breaks within our variables. As you should be able to see, the value of $FunctionCode below is the code that makes up a simple function. It includes the function keyword, a function name, an open curly brace, the function’s actual code — there’s three lines of it — and a closing curly brace, as well.

$FunctionCode = @'
Function Show-Info {
    '*****'
    'This is function Show-Info.'
    '-----'
}
'@

As expected, when I echo my variable’s value, I get back exactly what I put into it.

PS > $FunctionCode
Function Show-Info {
    '*****'
    'This is function Show-Info.'
    '-----'
}

Now, for the fun part. I’ll include all my code and then we can discuss it line by line below.

$FunctionCode = $FunctionCode -split '\n'
$FunctionCodeCount = $FunctionCode.Count - 2
$FunctionCode = $FunctionCode[1..$FunctionCodeCount]
$FunctionCode = $FunctionCode | Out-String

The first of the above four lines assigns the variable $FunctionCode the value stored in $FunctionCode after we split it on each new line. The second of the four lines creates a $FunctionCodeCount variable, assigning it the number of lines in $FunctionCode after having subtracted 2 from its value. See if you can figure why it’s two…

The third line reassigns $FunctionCode again. In this line we only return the contents of the function. This means it doesn’t return the first line of the function, which includes the function keyword, the function name, and the open curly brace. It also will not include the closing curly brace at the bottom. Our final line reassigns the $FunctionCode for a third time, taking its current value and piping that to Out-String. This will help us ensure we add back in our line breaks.

Before we create our Show-Info function, let’s take a look at the $FunctionCode variable value now.

PS > $FunctionCode
    '*****'
    'This is function Show-Info.'
    '-----'

Using Set-Item, we’ll create our function called Show-Info regardless of whether or not it already exists. That’s the difference between New-Item and Set-Item (and most New vs. Set commands). New-Item will only work if Show-Info doesn’t already exist, while Set-Item will work even if the function already exists. It if doesn’t, it’ll act like New-Item and create the function.

Set-Item -Path Function:\Show-Info -Value $FunctionCode

And finally, entering Show-Info invokes the newly created function.

PS > Show-Info
*****
This is function Show-Info.
-----

Okay, with all that out of the way, we’re going to hit the pause button. Be sure you get what’s happening here, because we’ll pick up on this post in a very soon to be released follow-up that includes the rest of what we’re after: creating a function with a random number of parameters and testing we can calculate that number correctly. If you see an area in which I can improve this, please let me know!

Before we sign off though, let me include all the above code in a single, below code block. That may end up being helpful to one of us.

Remove-Variable -Name FunctionCode,FunctionCodeCount -ErrorAction SilentlyContinue

$FunctionCode = @'
Function Show-Info {
    '*****'
    'This is function Show-Info.'
    '-----'
}
'@

$FunctionCode = $FunctionCode -split '\n'
$FunctionCodeCount = $FunctionCode.Count - 2
$FunctionCode = $FunctionCode[1..$FunctionCodeCount]
$FunctionCode = $FunctionCode | Out-String

Set-Item -Path Function:\Show-Info -Value $FunctionCode

Show-Info

Functions Finding Variable Values

Every once in awhile I forget something I know, I know. Not sure why, but for a quick moment, I suddenly couldn’t remember which can access what. Can a nested, or child, function, access the variable in the containing, or parent, function, or is it the other way around? That is, can a containing, or parent, function access the variable in the nested, or child, function? Even as I write this, I still can’t believe that for a moment I forgot what I’ve known for so long.

Duh. A nested or child function can access a variable assigned in the containing or parent function. If the child function cannot find a declared variable inside itself, it’ll go upward in scope to its mom or dad, and ask if they have the variable assigned, and if so, they can borrow it. Being good parents, they offer it if they have it.

It’s so obnoxious that in a quick moment, I wasn’t sure, even though I’ve pictured it in my own head multiple times, as well as relied on it. Anyway, here’s an example that does prove that a nested function will go upward to find a variable, if it’s not been assigned inside itself.

Function AAA {
    'In function AAA.'
    Function BBB {
        'In function BBB.'
        $x = 5
    }
    $x
    BBB
}
AAA

Function CCC {
    'In function CCC.'
    $x = 5
    Function DDD {
        'In function DDD.'
        $x
    }
    DDD
}
CCC
In function AAA.
In function BBB.
In function CCC.
In function DDD.
5

This got me wondering, how far up will it go!? I assume it’ll go up and up and up, and well I was right. Take a look at this example. I guess if I had to forget something so simple that at least I got an opportunity to build this example. Enjoy the weekend!

Function Top {
    $x = 10
    "0. Assigned `$x with $x."
    "1. Inside the $($MyInvocation.MyCommand.Name) function."
 
    Function MidTop {
        "2. Inside the $($MyInvocation.MyCommand.Name) function."
 
        Function MidBottom {
            "3. Inside the $($MyInvocation.MyCommand.Name) function."
 
            Function Bottom {
                "4. Inside the $($MyInvocation.MyCommand.Name) function."
                If (Get-Variable -Name x -Scope Local -ErrorAction SilentlyContinue) {
                    '5. Can find the variable in the local scope.'
                } Else {
                    '5. Cannot find the variable in the local scope.'
                }
                "6. The value of `$x is $x."
            } # End Function: Bottom.
            Bottom
 
        } # End Function: MidBottom.
        MidBottom
 
    } # End Function: MidTop.
    MidTop
 
} # End Function: Top.
Top
0. Assigned $x with 10.
1. Inside the Top function.
2. Inside the MidTop function.
3. Inside the MidBottom function.
4. Inside the Bottom function.
5. Cannot find the variable in the local scope.
6. The value of $x is 10.

Update: I made a few modifications to the above function. Now, it indicates that it cannot find the $x variable in the local scope of the Bottom function. That’s one way to help prove it goes upward through the parent functions looking for a value for $x.

Get Multiple Percentages of Multiple Values

Before my parents decided to trade in their truck at the dealership this week, we began to discuss the possibility of me selling it for them. Back when we started the discussion, I was thinking about possible prices for the truck, and the payout for me. Go figure, but, much like other things, I was able to incorporate Windows PowerShell into this, too.

Had this actually happened, we were going to need to determine how much I was going make in this deal. Here’s how I saw the options:

– They indicate an amount they want for the truck, and everything over that amount is mine.
– They give me a set dollar amount to sell the truck, regardless of the purchase price.
– They agree to a percentage of the final purchase price.

This last option was the one that had me flip over to my PowerShell console. You see, I often use the console as my calculator. I’m faster at typing out my math problems there, than I am using the built-in calculator in Windows.

Let’s use the possible purchase prices of $12,500, $13,000, $13,500, $14,000, and $14,500. In case you’re interested, it was a 2005 F150 SuperCrew Cab with under 70,000 miles — you read that right, less than 7,000 miles per year. What I wanted to determine was how much my parents and I would each make if I received 1%, 2.5%, 5%, 7.5%, 10%, and 12% of each of the possible purchase prices. Enter PowerShell.

The first thing I did was pipe each of the possible purchase prices to the ForEach-Object cmdlet and write their values to the screen. The results indicated that each value was properly crossing the pipeline.

12500,13000,13500,14000,14500 | ForEach-Object {
    Write-Output -Verbose $_
}
12500
13000
13500
14000
14500

Next, I created a variable for each percentage, based on a calculation. On the way into the loop, it would multiply the possible purchase price, of that iteration, by the percentage amount and store it in the proper variable. Notice that I have variables with dots (or periods, or decimals) in them, such as ${7.5Percent}. In order to use something other than a letter, number, or underscore, we need to wrap the variable in curly brackets. It’s not recommend to use variable with anything other than letters and numbers, but I thought it made sense in this case.

12500,13000,13500,14000,14500 | ForEach-Object {
    $12Percent = $_ * .12
    $10Percent = $_ * .1
    ${7.5Percent} = $_ * .075
    $5Percent = $_ * .05
    ${2.5Percent} = $_ * .025
    $1Percent = $_ * .01
}

After these variables were assigned, I created a header and footer that helped to separate the results from one another. Remember, each iteration through the loop prints these two lines of asterisks. Notice that the top row will include the current possible purchase price in the middle. The colors will also help separate the different purchase prices and the percentages.

12500,13000,13500,14000,14500 | ForEach-Object {
    $12Percent = $_ * .12
    $10Percent = $_ * .1
    ${7.5Percent} = $_ * .075
    $5Percent = $_ * .05
    ${2.5Percent} = $_ * .025
    $1Percent = $_ * .01

    Write-Host -Object "*****$_*****" -ForegroundColor Green

    Write-Host -Object '***************' -ForegroundColor Green
}

Here’s how this displayed at this point.

Get-Multiple-Percentages-of-Multiple-Values00

In this next example, you can see where included the 90% value and 10% value of each possible purchase price. To determine these two values, we subtracted our 10% amount from the full purchase price (for 90%). The second value was already determined as part of setting the variable at the beginning of the loop, so we echoed what was already in the variable.

12500,13000,13500,14000,14500 | ForEach-Object {
    $12Percent = $_ * .12
    $10Percent = $_ * .1
    ${7.5Percent} = $_ * .075
    $5Percent = $_ * .05
    ${2.5Percent} = $_ * .025
    $1Percent = $_ * .01

    Write-Host -Object "*****$_*****" -ForegroundColor Green

    Write-Host -Object "90%: $($_ - $10Percent)" -ForegroundColor Yellow
    Write-Host -Object "10%: $10Percent" -ForegroundColor Gray

    Write-Host -Object '***************' -ForegroundColor Green
}

Here’s what it looked like when the code above was run.

Get-Multiple-Percentages-of-Multiple-Values01

Here’s the final code and results.

12500,13000,13500,14000,14500 | ForEach-Object {
    $12Percent = $_ * .12
    $10Percent = $_ * .1
    ${7.5Percent} = $_ * .075
    $5Percent = $_ * .05
    ${2.5Percent} = $_ * .025
    $1Percent = $_ * .01

    Write-Host -Object "*****$_*****" -ForegroundColor Green

    Write-Host -Object "87.5%: $($_ - $12Percent)" -ForegroundColor Yellow
    Write-Host -Object "12.5%: $12Percent" -ForegroundColor Gray

    Write-Host -Object "90%: $($_ - $10Percent)" -ForegroundColor Yellow
    Write-Host -Object "10%: $10Percent" -ForegroundColor Gray

    Write-Host -Object "92.5%: $($_ - ${7.5Percent})" -ForegroundColor Yellow
    Write-Host -Object "7.5%: ${7.5Percent}" -ForegroundColor Gray

    Write-Host -Object "95%: $($_ - $5Percent)" -ForegroundColor Yellow
    Write-Host -Object "5%: $5Percent" -ForegroundColor Gray

    Write-Host -Object "97.5%: $($_ - ${2.5Percent})" -ForegroundColor Yellow
    Write-Host -Object "2.5%: ${2.5Percent}" -ForegroundColor Gray

    Write-Host -Object "99%: $($_ - $1Percent)" -ForegroundColor Yellow
    Write-Host -Object "1%: $1Percent" -ForegroundColor Gray

    Write-Host -Object '***************' -ForegroundColor Green
}

Get-Multiple-Percentages-of-Multiple-Values02

In the results, above, I’ve only included the first three possible purchase prices, to save space. While all of this could have been figured out with a calculator, there’s no possible way it could have been done as quickly — at least for someone that knows PowerShell. I didn’t bother to create an object in this instance, although it would have made sense. In my mind this wasn’t going to be reused any more than it was this one time, and so I didn’t add the additional effort.

I hope this is helpful for someone. Cheers.

Give your Variable a Description

When we think of variables in Windows PowerShell, we often only consider two parts: the name of the variable, and the value of the variable. Well, it turns out that those aren’t the only properties; let’s discuss the description property.

I can’t say I’ve ever added a description to a variable until now, but I can think of times, when looking at someone’s code, where I wish I knew the reason why a variable existed. Best practice would indicate we use meaningful names for our variables, so it’s probably safe to assume that the same people that might use a poorly-named variable, probably don’t know or care that variables can have descriptions… but, I digress.

In this first example, we’ll create a new variable using what I’d call the standard method — the equal sign assignment operator.

PS C:\> $a = 12345
PS C:\> $a
12345
PS C:\> Get-Variable a | Select-Object *

Name        : a
Description :
Value       : 12345
Visibility  : Public
Module      :
ModuleName  :
Options     : None
Attributes  : {}

In line 1, we created a new variable, $a, and set its value to the numeric 12345. In the next line, we simply echoed the variable’s value. In line 4, we used the Get-Variable cmdlet and piped it to the Select-Object cmdlet and * so we were able to view all of its properties. If you take a look at the results, you’ll see the description property, and notice that it’s currently blank.

In the next example, we’ll use the Set-Variable cmdlet to modify the variable’s description.

PS C:\> Set-Variable a -Description 'This variable contains a 5-digit number.'
PS C:\> Get-Variable a | Select-Object *

Name        : a
Description : This variable contains a 5-digit number.
Value       : 12345
Visibility  : Public
Module      :
ModuleName  :
Options     : None
Attributes  : {}

PS C:\>

Once we use the Get-Variable cmdlet, and return all the properties again, we can see that our variable now contains a description value. Now, while many user-defined variables, such as we created here, don’t often contain descriptions, many of the automatic and preference variables do — take a look at a segment of the results returned by the next command.

PS C:\> Get-ChildItem variable: | Select-Object Name,Description | Format-Table -AutoSize

Name                       Description
----                       -----------
...
MaximumAliasCount          Maximum number of aliases allowed in a session
MaximumDriveCount          Maximum number of drives allowed in a session
MaximumErrorCount          Maximum number of errors to retain in a session
MaximumFunctionCount       Maximum number of functions allowed in a session
MaximumHistoryCount        Maximum number of history objects to retain in a session
MaximumVariableCount       Maximum number of variables allowed in a session
MyInvocation
NestedPromptLevel          Dictates what type of prompt should be displayed for the current nesting level
...

Well, there you go: something you might not have known about, and something you may never use.

about_Variables

This post is the help rewrite for about_Aliases. While the help files for Windows PowerShell are invaluable, the idea behind a rewrite is so true beginners might even better understand the help file concepts. At times, some things discussed in the Windows PowerShell help file will not be included in a help rewrite. Therefore, it is always best to read the actual help file after reading this post. (PS3.0)

A variable in Windows PowerShell is a storage container in memory that can hold a value or values. Variables can store numbers, letters, strings (a sequence of numbers, letters, and/or other characters), and the results of a command that has been run in Windows PowerShell. Variables are defined by a dollar sign ($) and a string of text that follows.

PS C:\> $myVariable
PS C:\> $Process
PS C:\> $UserName
PS C:\> $a
PS C:\> $Var

Windows PowerShell has three types of variables. There are user-created variables, automatic variables, and preference variables. User-created variables are created by a user such as the variables in this example.

PS C:\> $Name = 'Macy Jones'
PS C:\> $Number = 10

Automatic variables store the state of Windows PowerShell, such as the $PSHOME variable, which stores the install location of Windows PowerShell. This type of variable cannot be changed by a user. This example shows what happens when a user tries to change the value of the $PSHOME automatic variable.

PS C:\> $PSHOME
C:\Windows\System32\WindowsPowerShell\v1.0
PS C:\> $PSHOME = 'C:\Windows'
Cannot overwrite variable PSHOME because it is read-only or constant.
At line:1 char:1
+ $PSHOME = ‘C:\Windows’
+ ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (PSHOME:String) [], SessionStateUnauthorizedAccessException
    + FullyQualifiedErrorId : VariableNotWritable

Preference variables store a default value but can be changed. These types of variables include the $MaximumAliasCount variable that stores the maximum number of aliases Windows PowerShell will store (the default value for this variable is 4096). This example shows how this variable’s value can be changed.

PS C:\> $MaximumAliasCount
4096
PS C:\> $MaximumAliasCount = 2000
PS C:\> $MaximumAliasCount
2000
PS C:\> $MaximumAliasCount = 4096

Variables are created by combining a dollar sign ($) and a text string. It is beneficial to name variables in such a way that the name helps define what the variable will store. Then use the = operator to assign, or set, the variable with a value. This example shows two variables, $Name and $Number, being set to two different values. To display the value assigned to a variable, type a dollar sign and the variable name and press Enter.

PS C:\> $Name = 'Macy Jones'
PS C:\> $Number = 10
PS C:\> $Series = 1,2,3
PS C:\> $Name
Macy Jones
PS C:\> $Number
10
PS C:\> $Series
1
2
3

The variable’s values can also be displayed using the Write-Output cmdlet, as well as the aliases for Write-Output, write and echo. This is used more often in scripts as opposed to the Windows PowerShell console.

PS C:\> Write-Output $Name
Macy Jones
PS C:\> write $Name
Macy Jones
PS C:\> echo $Name
Macy Jones

While the Write-Host cmdlet can also display a variable’s value, in most cases, it should not be used in place of Write-Output.

PS C:\> Write-Host $Name
Macy Jones

Variable names are not case-sensitive. The case of a variable name does not matter when it is assigned or used. This example also indicates how to assign a new value to a variable that already had a value.

PS C:\> $name
Macy Jones
PS C:\> $NAME
Macy Jones
PS C:\> $NamE
Macy Jones
PS C:\> $NAME = 'Lance Andrews'
PS C:\> $name
Lance Andrews
PS C:\> $name = 'Macy Jones'
PS C:\> $NAMe
Macy Jones

Variables can hold the results of commands. The first part of this example uses the Get-Process cmdlet to immediately display the first four running processes. In the second part of the example, the first four running processes are stored in a variable and then displayed when the variable is entered.

PS C:\> Get-Process | Select-Object -First 4

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    224      19     3436        772   110    16.80   4612 ALMon
    164      14     2476       2100    44     5.53   2744 ALsvc
     77       9     1336       5288    75   140.70   4076 ApMsgFwd
     90       8     1372       5852    76   162.11   4324 ApntEx

PS C:\> $Processes = Get-Process | Select-Object -First 4
PS C:\> $Processes

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    224      19     3436        772   110    16.80   4612 ALMon
    164      14     2476       2100    44     5.53   2744 ALsvc
     77       9     1336       5288    75   140.73   4076 ApMsgFwd
     90       8     1372       5852    76   162.11   4324 ApntEx

This examples sets, or assigns, the $Date variable to the results of the Get-Date cmdlet.

PS C:\> $Date = Get-Date
PS C:\> $Date

Thursday, May 01, 2014 9:20:30 PM

The Clear-Variable cmdlet, or clv alias, in this example, will remove the value that has been assigned to a variable without destroying, or removing, the variable itself. When referencing the variable, the dollar sign ($) is not used with either of these two cmdlets or with the Get-Variable cmdlet. The Get-Variable cmdlet will list all the variables in the session or list a single variable when a variable name is supplied.

PS C:\> $Name
Macy Jones
PS C:\> Clear-Variable Name
PS C:\> $Name
PS C:\> Get-Variable Name

Name                           Value
----                           -----
Name

The Remove-Variable cmdlet, or rv alias, in this example, will completely remove a variable and its stored value from memory.

PS C:\> $Color = 'Green'
PS C:\> $Color
Green
PS C:\> Remove-Variable Color
PS C:\> $Color
PS C:\>
PS C:\> Get-Variable Color
Get-Variable : Cannot find a variable with the name ‘Color’.
At line:1 char:1
+ Get-Variable Color
+ ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Color:String) [Get-Variable], ItemNotFoundException
    + FullyQualifiedErrorId : VariableNotFound,Microsoft.PowerShell.Commands.GetVariableCommand

Variables can store different types of data. Normally they make their type determination based on the value(s) assigned to them. They can store integers, strings, arrays, and more. A single variable, when it is an array, can contain different types of data at the same time. The examples below use the Get-Member cmdlet to return properties (and more) about our variable. The Select-Object cmdlet has also been used to help filter what is returned.

PS C:\> $a = 12
PS C:\> $a | Get-Member | Select-Object TypeName -Unique

TypeName
--------
System.Int32

PS C:\> $a = 'Word'
PS C:\> $a | Get-Member | Select-Object TypeName -Unique

TypeName
--------
System.String

PS C:\> $a = 12,'Word'
PS C:\> $a | Get-Member | Select-Object TypeName -Unique

TypeName
--------
System.Int32
System.String

A variable can be forced to be a certain type by casting the variable. In the first part of the example below, the variable $Number will be cast with an int type (int, as in, integer). Even though the variable is cast as an integer, it is able to handle being assign a string value of “12345.” This is because the variable can change that string into a numeric value. It cannot do the same thing with the string “Hello.”

Further down in the example, the $Words variable has been cast as a string. When it is set to a numeric value it converts the numeric value into a string value. If the variable is used in a mathematical equation, such as an addition equation, it does not add the two values and instead will concatenate, or join them.

PS C:\> [int]$Number = 10
PS C:\> $Number
10
PS C:\> $Number = '12345'
PS C:\> $Number
12345
PS C:\> $Number = 'Hello'
Cannot convert value “Hello” to type “System.Int32”. Error: “Input string was not in a correct format.”
At line:1 char:1
+ $Number = ‘Hello’
+ ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : MetadataError: (:) [], ArgumentTransformationMetadataException
    + FullyQualifiedErrorId : RuntimeException
PS C:\> [string]$Words = 'Hello'
PS C:\> $Words
Hello
PS C:\> $Words = 2
PS C:\> $Words
2
PS C:\> $Words + 10
210
PS C:\> $Number
12345
PS C:\> $Number + 10
12355

There are differences between using single quotes–which should be used as often as possible–and double-quotes. Single quotes around a variable will not expand the value stored in the variable; however, using double quotes will expand the variable.

PS C:\> $Name = 'Macy Jones'
PS C:\> 'Her name is $Name'
Her name is $Name
PS C:\> "Her name is $Name"
Her name is Macy Jones

Although variable names can include spaces and special characters, it should be avoided as it can quickly lead to confusion. Using spaces and special characters requires the variable name be enclosed in curly brackets {}.

PS C:\> ${!@#$} = 'Monday'
PS C:\> ${Favorite Day} = 'Friday'
PS C:\> ${!@#$}
Monday
PS C:\> ${Favorite Day}
Friday

Windows PowerShell creates a variable drive that looks and acts a lot like a file system drive. You can access data in the variable drive the same way things are accessed in a file system. The first example uses Get-ChildItem to get the first 4 folders in C:\Windows. The second example does the same thing but instead returns the first four variables in the variable drive.

PS C:\> Get-ChildItem C:\Windows | select -First 4

    Directory: C:\Windows

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----         11/5/2013   3:31 PM            ADAM
d----         7/13/2009  10:32 PM            addins
d----         7/13/2009   8:20 PM            AppCompat
d----         4/11/2014   5:22 PM            AppPatch

PS C:\> Get-ChildItem variable:\ | select -First 4

Name                           Value
----                           -----
!@#$                           Monday
$                              4
?                              True
^                              Get-ChildItem

The only other variable cmdlet that was not discussed is the New-Variable cmdlet. This cmdlet is often not used since a variable can be created without it. The first example below shows how to return all the variable-related cmdlets. The second example shows how to use New-Variable.

PS C:\> Get-Command *-Variable

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Cmdlet          Clear-Variable                                     Microsoft.PowerShell.Utility
Cmdlet          Get-Variable                                       Microsoft.PowerShell.Utility
Cmdlet          New-Variable                                       Microsoft.PowerShell.Utility
Cmdlet          Remove-Variable                                    Microsoft.PowerShell.Utility
Cmdlet          Set-Variable                                       Microsoft.PowerShell.Utility

PS C:\> New-Variable -Name DaysInYear -Value 365
PS C:\> $DaysInYear
365

Bonus Information

There may come a time when two (or more) variables need to be set to the same value. These do not need to be set individually. This first example shows how to set two variables at the same time and the second example shows how to set three variables at the same time.

PS C:\> $a = $b = 'Windows PowerShell'
PS C:\> $a
Windows PowerShell
PS C:\> $b
Windows PowerShell
PS C:\> $x = $y = $z = 42
PS C:\> $x
42
PS C:\> $y
42
PS C:\> $z
42

Real World

When values of a variable are displayed in the console, it will very rarely follow the Write-Output cmdlet. This cmdlet is most often used in scripts than it is with commands written in the console.

Learn More

This information, and more, are stored in the help file about_Variables that comes with Windows PowerShell. This information can be read by typing any of the commands below. The first example will display the help file in the Windows PowerShell console, the second example will open the full help in its own window, and the third example will send the contents of the help file to the clipboard (so it can be pasted into Word, Notepad, etc.), and the fourth example will open the help file in Notepad.

PS C:\> Get-Help about_variables
PS C:\> Get-Help about_variables -ShowWindow
PS C:\> Get-Help about_variables| clip
PS C:\> Notepad $PSHOME\en-us\about_Variables.help.txt