A Variable’s Current and Previous Value

How to Store a Variable’s Previous Value with the New Value

There was a recent post on the PowerShell Facebook group that said this: “Is there a function or option to check previous $Global:variable -ne Current $Global:variable?” The person that created the post wanted to know if there’s a way to recall the last value a variable stored, once it had already been assigned something new. Here’s my answer, and potential solution.

You have to think about a variable’s previous assignment, as if it never existed, even though you know that variable held something, or was assigned something, previously. Once its value is gone, it’s gone. Now, all that said, I came up with an option. The option, is to use a variable’s description property to store its previous value.

Let’s begin by checking the value of an uninitialized variable, and then assign it something.

PS > $x
PS > # No value.
PS > $x = 'first value'
PS > $x
first value

Now that our variable has a value, let’s take a look at all the variable’s properties using the Get-Variable cmdlet. Notice the Description property; we’re going to use this in a less than conventional way.

PS > Get-Variable -Name x | Select-Object -Property *

Name        : x
Description :
Value       : first value
Visibility  : Public
Module      :
ModuleName  :
Options     : None
Attributes  : {}

Using the Set-Variable cmdlet, we’ll make two modifications to our variable, at nearly the same time. First, we’ll update the Description property, so that it’s holding the original variable assignment (the string ‘first value’). In the same, Set-Variable command, we’ll modify the current value of the variable to the string ‘second value.’ Notice in the final below command, that our Description property has a value now, too.

PS > Set-Variable -Name x -Value 'second value' -Description $x
PS > $x
second value
PS > Get-Variable -Name x | Select-Object -Property *

Name        : x
Description : first value
Value       : second value
Visibility  : Public
Module      :
ModuleName  :
Options     : None
Attributes  : {}

In the next example, you’ll see how we can return the original value and the variable’s updated value. Beneath that, I’ve included a couple ways to compare these values. That gets back to what the person on Facebook was trying to determine. Again, this is fairly unconventional use of the Description property, but it does avoid the need for a second variable to hold the first variable’s original value. That said, one of my examples uses a second, comparison variable.

PS > (Get-Variable -Name x).Description
first value
PS > (Get-Variable -Name x).Value
second value
PS > $x
second value

PS > (Get-Variable -Name x).Description -ne (Get-Variable -Name x).Value
True
PS > (Get-Variable -Name x).Description -ne $x
True
PS > $y = (Get-Variable -Name x).Description
PS > $y -ne $x
True

In these last examples, we’re running into a bit of a problem, we are going to have to keep in mind (if anyone even dares use this approach). When we take a value that isn’t a string, and place it into the Description property, it becomes a string. That means, that when we take it back out, we’ll need to cast it back to its proper type. Take a look at the next series of examples for some assistance with this concept.

PS > $z = 5
PS > Set-Variable -Name z -Value 10 -Description $z
PS > Get-Variable -Name z | Select-Object -Property *

Name        : z
Description : 5
Value       : 10
Visibility  : Public
Module      :
ModuleName  :
Options     : None
Attributes  : {}

PS > (Get-Variable -Name z).Description | Get-Member |
>>> Select-Object -Property TypeName -Unique

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

PS > [int](Get-Variable -Name z).Description
5
PS > [int](Get-Variable -Name z).Description | Get-Member |
>>> Select-Object -Property TypeName -Unique

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

This goes for decimals values, too. If you use the Description property to store something that’s not a string, then you’re going to have to properly cast it when you’re taking it out, or you’re going to have a string. In these next examples, I used the GetType method to determine the value’s type, as opposed to Get-Member and Select-Object used above.

PS > $m = 2.5
PS > $m.GetType().Name
Double
PS > Set-Variable -Name m -Value 3.5 -Description $m
PS > $m
3.5
PS > $m.GetType().Name
Double
PS > (Get-Variable -Name m).Description
2.5
PS > (Get-Variable -Name m).Description.GetType().Name
String
PS > [double](Get-Variable -Name m).Description
2.5
PS > ([double](Get-Variable -Name m).Description).GetType().Name
Double

And that’s it. It’s may not be the first choice for saving a previous variable’s value, but it’s a choice. I rather liked the array option that was recommended; however, like the $Error array, I’d be tempted to put the newest/current value of a variable into index 0 and not at the end of the array. Anyway, back to real life now.

Leave a Reply

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