Recently I was experimenting with passing arguments into a function or a script. I wanted to see how variable length argument functions or scripts could be created. Here’s what I had set up in my test script:
I then saved this script as test.ps1 and called it in PowerShell like this:
.\test.ps1 “1” “2” “3”
Naturally I expected to see the string values “1”, “2”, and “3” output to the console, each on their own line.
Instead, here is the output I received:
That’s odd. Some arguments were output, but not all of them. What happened to the first argument that I passed in?
In this example, when I execute the test.ps1 script, the PowerShell interpreter looks at the arguments I am passing in and attempts to assign them to the arguments that this script accepts as declared in the param statement. I only have one argument in my param statement, so PowerShell takes the first argument that was passed in and converts it into the type of the argument declared in the param statement. That means my “1” string gets converted into an array of strings. Then PowerShell looks at any remaining arguments and it stores them in an array in the $args variable. This is a system variable that is used to store all remaining arguments that aren’t matched up to arguments declared in the param statement.
Looking at my example, you can see that I am using the $args variable in my param statement. This means that when the script is run the first value is converted into an array of strings that is stored in the args variable. Then the args variable is cleared and the remaining arguments are added to the $args variable array. Once they are all added, the script is run and the last two arguments are output to the console. As a result, the first argument gets discarded.
It is interesting to note that when you do this, the $args variable retains its array of strings type within the script. By default, $args is an array of objects. If you comment out the param statement in the script, the script will output all objects to the console, and the $args variable will store those objects in an array of type object as expected.
Lesson learned? Don’t use the $args variable as an argument to a function or a script.