37

I have a test powershell V2 script that looks like this:

    function test_args()
    {
      Write-Host "here's arg 0: $args[0]"
      Write-Host "here's arg 1: $args[1]"
    }


    test_args

If I call this from the powershell command prompt I get this on the screen:

here's arg[0]: [0]

here's arg[1]: [1]

Not quite what I wanted. It seems I have to copy $args[0] and $args[1] to new variables in the script before I can use them? If I do that I can access things fine.

Is there a way to access the indexed $args in my code? I've tried using curly braces around them in various ways but no luck.

I'll be moving to named parameters eventually, but the script I'm working on (not this demo one) is a straight port of a batch file.

larryq
  • 15,713
  • 38
  • 121
  • 190
  • 3
    Ultimately, this is string-expansion (interpolation) syntax problem, as also explained in the accepted answer. In short: To embed an _expression_ such as `$args[0]` - as opposed to a mere variable reference such as `$var` - you need `$(...)`, the subexpression operator; ergo: `"... $($args[0]) ..."`. For a concise summary of PowerShell's string-expansion rules, see [this answer](https://stackoverflow.com/a/40445998/45375). – mklement0 Nov 15 '19 at 16:18

1 Answers1

60

Try this instead:

function test_args()
{
  Write-Host "here's arg 0: $($args[0])"
  Write-Host "here's arg 1: $($args[1])"
}

test_args foo bar

Note that it is $args and not $arg. Also when you use a PowerShell variable in a string, PowerShell only substitutes the variable's value. You can't directly use an expression like $args[0]. However, you can put the expression within a $() sub-expression group inside a double-quoted string to get PowerShell to evaluate the expression and then convert the result to a string.

Keith Hill
  • 194,368
  • 42
  • 353
  • 369
  • Thank you Keith-- I changed my snippet to correct my typo when translating from my editor to SO. I guess my question is, do I need to pass $arg[0] and [1] to test_args as parameters, or will the function itself have access to the $args array? – larryq Sep 07 '12 at 22:34
  • 12
    Functions always have access to $args. It will contain any argument that doesn't map to a defined function parameter. If there are no arguments or all the arguments map to function parameters e.g. `function foo($param1, $param2){}` then $args will be an empty array. – Keith Hill Sep 07 '12 at 22:41
  • Sometimes I have to use `Out-String` to get the output of a sub-expression to display as desired ... such as when working with a hashtable. Example, assumes arg 1 is a hashtable: `Write-Host "here's arg 1: $($args[1] | Out-String)"` – VertigoRay Sep 26 '14 at 22:29
  • 3
    Small caveat re `$args` availability: _Advanced_ functions (or scripts) - namely those whose `param()` block is decorated with the `[CmdletBinding()]` attribute and/or whose parameters are decorated with `[Parameter()]` attributes - fundamentally do not permit invocation unless _all_ arguments passed bind to _declared_ parameters. In other words: `$args` does not apply to advanced functions and scripts. – mklement0 Nov 15 '19 at 16:23
  • I use $args in function n{notepad $args} and call it with n argg_file. This seems PS kungfu? – Timo Oct 21 '20 at 19:11