PowerShell How-To

Exploring Reference Variables in PowerShell

Even if you've heard of reference variables, their use may still be a mystery.

You've heard of variables in PowerShell, right?  How about reference variables?  Maybe not.  The reason is because a scripter can generally get by without them, but they do still have a purpose.

PowerShell has a concept known as scopes.  You can think of scopes as a hierarchical stack of boxes that variables live in.  This is similar to how Russian Matryoshka dolls work.  Each "box" fits neatly into the next biggest box and so on until the biggest box contains all of the smaller boxes.  Inside of each PowerShell function is the function's "box" or scope.  Typically, variables that are defined in a function do not exist outside of that function's scope.

I've created a function with a single parameter $Param.  Any integer passed to this function adds 10 to it.

function Add-Ten  {

param($Param)

$Param = $Param + 10

}

I have created a variable in my console called $Number and have given it a value of 5.

$Number = 5

My intention is to pass this variable to my function, and I expect $Number to be 15 when it's done, right?

[Click on image for larger view.] 

Nope, $Number is still 5.  Why?  The reason is because of scoping.  The variable $Number created directly in my console is different than the variable $Number that's defined in the function.  This is how scoping works.  You can have any number of variables with the exact same name, and that variable name will represent different values in different scopes.

Now let's modify this function to pass a reference variable and try again.

function Add-Ten  {

param([ref]$Param)

$Param = $Param + 10

}

[Click on image for larger view.] 

Notice how I enclosed the parameter argument in parentheses?  This is another requirement of passing variables by reference.  Even though we did everything right, it still didn't work! The reason is because when passing variables by reference, things get a little hairy.  When passing variables by reference, you're actually passing the entire object; not just the value.  This is why you must append .Value in order for it to actually add 10 to it.

function Add-Ten  {

param([ref]$Param)

$Param.Value = $Param.Value + 10

}

[Click on image for larger view.] 

You can see that 10 was now added to $Number. What would this look like if I wanted to accomplish the same thing, only this time without using reference variables? First, I would change our function back to the original, but I'd add a single line at the end to simply output the value of $Param.  This tells the function to output the value of $Param immediately after it's added 10 to it.

function Add-Ten  {

param($Param)

$Param = $Param + 10

$Param

}

After the function has been modified to output the value, it's then a matter of assigning that value to $Number, which will then add 10 to it just like we did via reference earlier.

[Click on image for larger view.] 

You can see that this method is simpler and easier understood.  You also don't have to remember to enclose the reference variable in parentheses or remember to append the .Value property to the variable being assigned.

Reference variables have a very limited use, but when you do need to know them, it's good to have something to reference, and I'm glad to oblige.

About the Author

Adam Bertram is a 20-year veteran of IT. He's an automation engineer, blogger, consultant, freelance writer, Pluralsight course author and content marketing advisor to multiple technology companies. Adam also founded the popular TechSnips e-learning platform. He mainly focuses on DevOps, system management and automation technologies, as well as various cloud platforms mostly in the Microsoft space. He is a Microsoft Cloud and Datacenter Management MVP who absorbs knowledge from the IT field and explains it in an easy-to-understand fashion. Catch up on Adam's articles at adamtheautomator.com, connect on LinkedIn or follow him on Twitter at @adbertram or the TechSnips Twitter account @techsnips_io.


comments powered by Disqus
Most   Popular