问题
I have a script that require 2 arrays as input, and optional logname :
#file:test.ps1
Param(
[string[]]$array1,
[string[]]$array2,
[string]$logName = "log{0}.csv" -f (get-date -format "yyyyMMdd")
)
"array1: {0}" -f ($array1 -join " ")
"array2: {0}({1})" -f ($array2 -join " ") ,$array2.count
"logName: {0}" -f $logName
When run from a PowerShell console, everything is fine:
PS D:\temp> .\test.ps1 -array1 one,two -array2 1,2,3 array1: one two array2: 1 2 3(3) logName: log20190723.csv
But when run by calling powershell.exe (for scheduled task), only first element from array is grabbed, the rest is passed to the logname parameter.
PS D:\temp> powershell.exe -F D:\temp\test.ps1 -array1 one,two -array2 1,2,3 array1: one array2: 1(1) logName: two
How should I define params to grab all params into the array?
(BTW: I'm using PS4.0, with same result on Windows 2008 and 2012)
回答1:
TL;DR: You cannot pass PowerShell arrays across process boundaries.
The first invocation of your script runs within the current PowerShell process, hence one,two and 1,2,3 are passed as PowerShell arrays.
The second invocation of your script launches a second PowerShell process as an external program, thus taking a detour leaving and re-entering PowerShell. Because of that one,two and 1,2,3 are passed to the second PowerShell process as strings, not as arrays, since Windows doesn't know anything about PowerShell arrays.
You could split the parameter values at commas at the beginning of your script to mitigate this limitation:
Param(
[string[]]$array1,
[string[]]$array2,
[string]$logName = "log{0}.csv" -f (Get-Date -Format "yyyyMMdd")
)
if ($array1.Count -eq 1) { $array1 = $array1.Split(',') }
if ($array2.Count -eq 1) { $array2 = $array2.Split(',') }
Note, however, that this might cause problems when you're passing a single argument that contains commas.
Addendum: the behavior you describe for the second invocation should only occur when you have whitespace before or after a comma:
PS C:\> powershell.exe -F C:\path\to\test.ps1 -array1 one, two -array2 1, 2, 3 array1: one array2: 1(1) logName: two
Otherwise the output should be like this:
PS C:\> powershell.exe -F C:\path\to\test.ps1 -array1 one,two -array2 1,2,3 array1: one,two array2: 1,2,3(1) logName: log20190723.csv
回答2:
Use -c instead of -f (command instead of file) (or use neither):
powershell.exe -c D:\temp\test.ps1 -array1 one,two -array2 1,2,3
array1: one two
array2: 1 2 3(3)
logName: log20190723.csv
来源:https://stackoverflow.com/questions/57162074/passing-parameter-array-to-powershell-exe