Understanding $args in PowerShell
-
@chutestrate said:
I definitely am. Unfortunately, i don't see it the way you are telling me.
If I could figure out how you are perceiving it then maybe I could help more. I'm not sure how you are looking at it, though, which makes it hard for me.
-
Trying to sort it out. The automation piece is part of it. If it's created automatically why is the programmer designating what $args[0], [1], [2], etc is.
-
@chutestrate said:
Trying to sort it out. The automation piece is part of it. If it's created automatically why is the programmer designating what $args[0], [1], [2], etc is.
The programmer is not designating what they are. The programmer is reading the contents out. At no point, in any example, did we specify in our program what the values of the elements in the $args array were. We never did that. All we ever did was print out their contents to show what they had been set to by PowerShell.
-
Let me take a stab at explaining an array. It's just a list. When you write your groceries on a piece of paper you have a variable with multiple values on it. You don't write a single item per piece of paper, right? If you did that'd be a regular variable. Instead you put the whole list on one piece of paper, making it an array/list.
Computers are great with lists, but they have some limitations, and they have to be told to do things in a very literal sense. So, grocery list is:
$GroceryList = "beer","wine","whiskey","brandy","vodka","chips"
In PowerShell, the comma's are what tell PowerShell that this is an array. Now, if I ask you what's the 3rd item in the list, you would scan through and count each one, until you got to "whiskey". PowerShell is the same way, but we can jump straight to the third item. Try:
$GroceryList[3]
The brackets with the number tell PowerShell that you want to reference a particular item in the array. The number tells you which item. So we got Whiskey, right? If you tried it, you know we got "brandy". WTF? In programming languages, and this is pretty much universal, arrays always start at zero. So $GrocyerList[0] is beer, $GroceryList[1] is wine, and last $GroceryList[2] is whiskey. So when working with arrays you'd really want to:
$GroceryList[2]
To have PowerShell return the 3rd element. Each item in an array is called an element, by the way. Looking back at Scott's code, what he was doing was creating a For/Next loop, which is a loop using a number as reference.
for ($i = 0; $i -lt $GroceryList.Count; $i ++)
Is some goofy looking stuff, but the first part $i = 0 marks our starting point. $i = 0. The next part is a IF statement, that as long as it's true we'll continue the loop. In PowerShell we have built in properties, and one of those is Count which tells us the number of elements in the array. So as long as our $i variable is less then that count, we'll keep looping in the for loop. The last part $i ++ tells the loop, that when I'm done with the loop add one. The ++ thing is basically shorthand for $i = $i + 1.
Now PowerShell will continue to run the code contained in the scriptblock (all the code between the curly brackets) until our $i variable equals or is greater than the number of elements in our $GroceryList. So the first time through the loop $i = 0, we display that number, and we reference the element in our array that corresponds with zero. Which is beer. Loop ends, $i increments to 1, start again.
Loop displays the number 1, and shows the $GroceryList element that corresponds to that number, which happens to be "wine". Code block ends, $i increments to 2. This is still less the $GroceryList.Count (which is 6, btw) so the loop repeats. Onward until $i get's to 6, at which point it exits the loop and continues on with the script. In this case there is no more script, so it exits the script and drops you back into the shell.
-
I'm actually following that. But the $args to array thing....
This isn't stating that $args is?
for ($i=0; $i -lt $args.length; $i++) {
"This is `$args[$i], which is: $($args[$i])"
} -
@chutestrate said:
I'm actually following that. But the $args to array thing....
Not $args to array. $args is the name of an array that is created at the time that the program is called.
-
@chutestrate said:
This isn't stating that $args is?
for ($i=0; $i -lt $args.length; $i++) {
"This is `$args[$i], which is: $($args[$i])"
}No, never is any value of $args set here. This is a for loop that simply counts from zero to "however long the array is." And it prints out the value of each element of the array one after another.
If this was setting the values in the array there would need to be details in this like the names or whatever, but none of that is here. This is just inspecting the existing array. We never create or modify the array in any way. All we are doing is looking at it.
-
Ok, so is this explanation misleading or am I just not reading it correctly. This is where I started going crazy with args.
There is a special variable $Args which contains an array of the parameters passed to a function. Let’s use this variable to show how we can pass an argument using string expantion.
Function HAL {“What are you doing $args ?”}<enter>
Type in the FunctionName and an Argument:
HAL DaveYou can use multiple $Args variables to pass more than one parameter.
-
@chutestrate said:
There is a special variable $Args which contains an array of the parameters passed to a function. Let’s use this variable to show how we can pass an argument using string expantion.
Function HAL {“What are you doing $args ?”}<enter>
Type in the FunctionName and an Argument:
HAL DaveYou can use multiple $Args variables to pass more than one parameter.
Oh my, you've gone down the rabbit hole. I see that you are reading this page which is horribly written for teaching:
http://www.powershellpro.com/powershell-tutorial-introduction/powershell-functions-filters/This is super confusing because of calling functions directly from the command line. Stop trying to use this, this is very hard to read and understand for no good reason. This is accurate, but much more complex and way past the point where you are now. Right now you are just trying to learn the most basic data structures. This is beyond what we've been talking about here (but doesn't conflict in any way.)
-
Nothing in there is wrong or different, he's just adding a complex example of creating a function directly from the command line rather than making a program and calling it that way. There is absolutely no reason to be adding that confusion here. Let's learn this material first then learn how to do that and how that is just another way of looking at what we have already covered.
-
Yeah, I'm kinda good like that, not in a good way. Ok, done with that then. Well, that is the source of my confusion of the "args is an array" now that I'm re reading it.
ok
-
I think the complexity there is that he is calling things in "yet another way." It's good to learn that you can do that (calling a function directly loaded into memory rather than running a full program that you saves) but it is just introducing too many concepts at once rather than one at a time and giving each a chance to sink in before providing the next one.
I find the new system of showing people live shells before teaching them full programs to not be a good one for understanding what programs are doing. But that might just be my old school years talking. I started programming on BASIC in 1985 so my perspective on learning languages is rather tainted by the era in which I did it.
-
Well for whatever reason I just lost power so maybe it's a good reason to look things over again tomorrow. Plus trying to type on phone is tough. I'll try to make the connection of $args again.
-
Fun. Lots of snow there in PA? I hope that the weather is good, I have to fly to San Francisco in the morning and I'm not far from PA.
-
No snow. Just my part of the block. Have a safe trip
-
Thanks. Lifting off about noon and heading south first thing, so probably safe. Nothing is delayed so far.
-
This has been a great discussion. I'm learning a bit about PowerShell just from this.
-
Yes, very good discussion. Did I just see @Rob-Dunn pop in too?
-
I was on my phone; Martin sent me a PM over at SW
I had responded to this question over there in the Powershell forum, but chutestrate's account is in moderation for some reason.
Anyway - I'll try to take a stab at this.
As mentioned, when you run a script or a function, powershell has a built-in mechanism that will interpret anything passed after that script or function (that are not named parameters) and places them into an $arg *object.' It's kind of like a basket that catches the other stuff passed that hasn't been explicitly handled in the script/function. Since someone could feasibly pass more than one argument to the script, Powershell needs to have a way to handle more than one argument...just in case. With that being said, there's always an $arg object, whether you've passed arguments or not. It's just there to handle anything that fall outside named parameters during execution.
Remember, everything is an object in Powershell. It can represent one thing or many things. In this case, $arg is an object that represents many things; i.e an array. $arg is a representation of that array.
So, you might run a script like this:
test.ps1 -ComputerName <COMPUTER_NAME> -ProcessName <PROCESS_NAME> more arguments
or even like this:
test.ps1 -ComputerName <COMPUTER_NAME> -ProcessName more <PROCESS_NAME> arguments
Since we've specified -ComputerName and -ProcessName, those are named parameters (as denoted by the dash '-' followed by the name of the parameter you are passing.), so anything that is passed outside of those named parameters will be placed into the $arg object. In either of the above examples, $arg[0] would be 'more' and $arg[1] would be 'arguments.' Like Scott and Martin said, $arg is an array, and in the script/function, the [0] and [1] just helps identify which item in the array we want to return.
-