I've looked all over, and I can't find the answer. If this is a duplicate, please point me to the question, but most things I've seen have answers that go around in circles and talk bout all sorts of complicated things with no direct answer.
My question is simple. I have the following Windows batch file foo.bat
:
@ECHO OFF
bar.exe %*
If I call foo.bat foobar 123
from the command line, it invokes bar.exe foobar 123
. This works with no command-line arguments. This works with multiple command-line arguments.
What is the equivalent PowerShell script that does basically the same thing: invoke another executable, passing all CLI parameters the user provided?
I wouldn't expect this would be difficult, but I sure can't find any straightforward answer.
CodePudding user response:
The PowerShell equivalent of your foo.bat
file is:
bar.exe @args
PowerShell exposes all (unbound) positional arguments[1] as an array stored in the automatic $args
variable.
By prefixing $args
with @
instead of $
, argument splatting is employed, which means that the elements of the $args
array are passed as individual arguments to bar.exe
- Note: This isn't strictly necessary when calling external programs (such as
bar.exe
) -$args
would work there too - but is more versatile in that it can also pass named arguments correctly through to other PowerShell commands, which typically have declared parameters that can be bound by name (e.g.,-Path C:\temp
to bind valueC:\temp
to declared parameter-Path
)
As for working with $args
in general:
$args.Count
tells you how many (unbound) positional arguments were passed,$args[0]
returns the first such argument,$args[1]
the second, and so on.
However, it is usually preferable to formally declare parameters in PowerShell scripts and functions, which can then also be bound by name (e.g., -FooParam foo
instead of just foo
). See this answer for more information.
[1] If your script doesn't formally declare any parameters (via a param(...)
block - see about_Scripts and the linked answer), all arguments are by definition unbound (i.e. not mapped to a declared parameter) and positional (not prefixed by a target parameter name). However, if your script does declare parameters, $args
only contains those arguments, if any, that were passed in addition to those binding to declared parameters. If your script is an advanced script (or function), $args
isn't supported at all, because passing unbound arguments is then categorically prevented. See this answer for more information.