Reputation: 641
I have a script that uses multiple arguments, some of which contain spaces. The script is called from another script, so I pass the arguments to it from variables with the calling script.
Calling script:
$script = "C:\Path\script.ps1"
$arg1 = "SomeValue"
$arg2 = "1234"
$arg3 = @("Value1","Some Value","Value 2")
$arg4 = $true
Invoke-Command $script -Arg1 $arg1 -Arg2 $arg2 -Arg3 $arg3 -Arg4 $arg4
The called script looks like this:
param (
[Parameter(Mandatory=$false,Position=0)]
[String]$arg1,
[Parameter(Mandatory=$false,Position=1)]
[String]$arg2,
[Parameter(Mandatory=$false,Position=2)]
[array]$arg3,
[Parameter(Mandatory=$false,Position=3)]
[bool]$arg4
)
# Do stuff with the arguments
When I call the script, I get the following error:
"A positional parameter cannot be found that accepts argument 'Some'."
I've also manually called the script (bypassing the calling script) in a powershell window as below:
powershell.exe -ExecutionPolicy bypass C:\Path\script.ps1 -Arg1 "SomeValue" -Arg2 "1234" -Arg3 @("Value1","Some Value","Value 2") -Arg4 $true
powershell.exe -ExecutionPolicy bypass C:\Path\script.ps1 -Arg1 "SomeValue" -Arg2 "1234" -Arg3 "Value1","Some Value","Value 2" -Arg4 $true
powershell.exe -ExecutionPolicy bypass C:\Path\script.ps1 -Arg1 "SomeValue" -Arg2 "1234" -Arg3 "Value1","SomeValue","Value2" -Arg4 $true
powershell.exe -ExecutionPolicy bypass C:\Path\script.ps1 -Arg1 "SomeValue" -Arg2 "1234" -Arg3 "Value1,SomeValue,Value2" -Arg4 $true
None of these variations work. I've also tried the ideas found here by changing the Arg3 value to (,$args) but that doesn't work. I also changed the parameter type as found here, but that didn't work either.
The goal is to be able to pass multiple variables (some with spaces) to the script through an argument/parameter.
EDIT 12/22/16: The goal includes passing this same information from a shortcut/typed command. For example, my calling script creates a RunOnce entry in the registry to reference the called script and places the arguments in the call just like the manual examples above. None of them work, either.
Set-ItemProperty $RegROPath "(Default)" -Value "powershell.exe -ExecutionPolicy Bypass $scriptPath $argumentList" -type String
Upvotes: 2
Views: 10893
Reputation: 4173
Replace Invoke-Command
With &
or .
Use &
if all you want is output, .
if you want it to run in the current context (e.g. retain all variables set)
Get-Help about_Scripts
for more detail (or read online version here)
Edit: Forgot to mention, it's not your script that is throwing that error, it's Invoke-Command
. If you absolutely have to use Invoke-Command
you need (running remotely for example) to pass the arguments as the parameter ArgumentList
like this:
$script = "C:\Path\script.ps1"
$argumentList = @(
'-arg1 "SomeValue"',
'-arg2 1234',
'-arg3 @("Value1","Some Value","Value 2")',
'-arg4 $true'
)
Invoke-Command -FilePath $script -ArgumentList $argumentList
Edit 2:
I will try your suggestion as soon as I am able to. One question, what if I need to add a conditional argument? Currently, I add arguments to the list with $argumentlist += ("arg5", "value"). Some of them are conditional: if ($bool) {$argumentlist += ("arg5", "value")}. Is there a way to do that in your example?
Yes you can, the $argumentList
variable in the example is an array like any other. It can be defined all at once, defined empty and added to later, or any mix.
Example
$argumentList = @(
'-arg1 "SomeValue"',
'-arg2 1234',
'-arg3 @("Value1","Some Value","Value 2")',
'-arg4 $true'
)
if ($bool) {
$argumentList += '-arg5 "value"'
}
Invoke-Command -FilePath $script -ArgumentList $argumentList
But again, unless you are running the command on a remote computer or PSSession, you should use &
or dot sourcing (.
). You can still add arguments conditionally using splatting (about_Splatting)
Example
$scriptParamsSplat = @{
arg1 = "SomeValue"
arg2 = 1234
arg3 = @("Value1","Some Value","Value 2")
arg4 = $true
}
if ($bool) {
$scriptParamsSplat.arg5 = "value"
}
& 'C:\Path\To\script.ps1' @scriptParamsSplat
Upvotes: 2