Assume I have (In file test.ps1
):
param (
[string[]] $one
)
Write-Host $one.Count
If I do:
powershell -File test.ps1 -one "hello","cat","Dog"
I get:
1
But I expect:
3
Why?
Assume I have (In file test.ps1
):
param (
[string[]] $one
)
Write-Host $one.Count
If I do:
powershell -File test.ps1 -one "hello","cat","Dog"
I get:
1
But I expect:
3
Why?
"-one" is getting passed in as a whole string as the converting happens before calling the method.
You could alternatively call it like the following
powershell -Command {.\test.ps1 -one "hello","cat","Dog"}
To complement Kevin Smith's helpful answer:
The only way to pass an array to a PowerShell script via the PowerShell CLI (powershell.exe
; pwsh
for PowerShell Core) is to use -Commmand
(-c
).
-File
interprets the arguments as literal values, and does not recognize arrays, variable references ($foo
), ...; in the case at hand, the script ends up seeing a single string with literal contents hello,cat,Dog
(due to double-quote removal).From inside PowerShell:
Use -Command
with a script block ({ ... }
), as shown in Kevin's answer, which not only simplifies the syntax (just use regular syntax inside the block), but produces type-rich output (not just strings, as with other external programs), because the target PowerShell instance uses the CLIXML serialization format to output its results, which the calling session automatically deserializes, the same way that PowerShell remoting / background jobs work (as with the latter, however, the type fidelity of the deserialization is invariably limited; see this answer).
Note, however, that from within PowerShell you generally don't need the CLI, which creates a (costly) child process, and can just invoke a *.ps1
script file directly:
.\test.ps1 -one hello, cat, Dog
From outside PowerShell - typically cmd.exe
/ a batch file - use -Command
with a single, double-quoted string containing the PowerShell code to execute, given that using script blocks isn't supported from the outside.
powershell -Command ".\test.ps1 -one hello, cat, Dog"
Note that, with -Command
, just as with direct invocation inside PowerShell, you must use .\test.ps1
rather than just test.ps1
in order to execute a file by that name in the current directory, which is a security feature.
Also note that with your simple argument values, "..."
-enclosing them is optional, which is why the commands above use just hello, cat, Dog
instead of "hello", "cat", "Dog"
; in fact, using embedded "
chars. in an overall "..."
command string can get quite tricky - see this answer.