Split: Passing Parameters to Invoke-Command

Hello,

I need help with parameter passing using Invoke-Command within a PSSession. I have a program on a remote computer that I need to execute and this program requires to have some parameter inputs.
Some of these parameters have spaces in them. I have tried to create the script block as shown below and use the Invoke-Command cmdlet to invoke this program withing a PSSession, but it complains about the -p parameter being ambiguous.

$Computer = ‘MYCOMPUTER’
$RemoteInstance = ‘SQLInstance’
$RemoteJob = ‘My SQl Job Name’
$SQLDomain = ‘MYDOMAIN’
$timeLimit = ‘123’
$RunMode = ‘start’

$Script = [ScriptBlock]::Create(@"
Start-Process D:\Application\app.exe -ArgumentList -i $RemoteInstance -j “$RemoteJob” -d $SQLDomain -t $timeLimit -p $RunMode
"@)

After I have created a PSSession, I use the following invoke command to invoke the program on the remote computer.

Invoke-Command -ComputerName $computer -ScriptBlock $Script

I got the error message as shown below:

Parameter cannot be processed because the parameter name ‘p’ is ambiguous. Possible matches include: -PassThru -FilePath.
+ CategoryInfo : InvalidArgument: (:slight_smile: [Start-Process], ParameterBindingException
+ FullyQualifiedErrorId : AmbiguousParameter,Microsoft.PowerShell.Commands.StartProcessCommand

How can get around this -p ambiguous error and get this invoke command to work?

Thanks you.

Instead of trying to use [scriptblock]::Create() to pass “parameters”, just use actual parameters. There are two ways you can do this, depending on whether you’re using PowerShell 3.0 or later on both sides of the connection:

# The easier PowerShell 3.0 way, the $using: scope modifier:

Invoke-Command -ComputerName $computer -ScriptBlock {
    Start-Process D:\Application\app.exe -ArgumentList -i $using:RemoteInstance -j "$using:RemoteJob" -d $using:SQLDomain -t $using:timeLimit -p $using:RunMode
}

# The PowerShell 2.0-compatible way, using the -ArgumentList parameter of Invoke-Command.  These parameters are passed by position,
# so make sure the order you use in the -ArgumentList parameter matches the order in the script block's parameters.

$scriptBlock = {
    param ($RemoteInstance, $RemoteJob, $SQLDomain, $timeLimit, $RunMode)

    Start-Process D:\Application\app.exe -ArgumentList -i $RemoteInstance -j "$RemoteJob" -d $SQLDomain -t $timeLimit -p $RunMode
}

Invoke-Command -ComputerName $computer -ScriptBlock $scriptBlock -ArgumentList ($RemoteInstance, $RemoteJob, $SQLDomain, $timeLimit, $RunMode)

Thank you for the response.

I tried both methods you showed me, but both generates the same error as before:

Parameter cannot be processed because the parameter name ‘p’ is ambiguous. Possible matches include: -PassThru -FilePath.
+ CategoryInfo : InvalidArgument: (:slight_smile: [Start-Process], ParameterBindingException
+ FullyQualifiedErrorId : AmbiguousParameter,Microsoft.PowerShell.Commands.StartProcessCommand
+ PSComputerName : MYCOMPUTER

Oh, missed that part. The -ArgumentList parameter to Start-Process takes an array of strings (though you can do just a single string if you prefer); you need to quote your stuff there so PowerShell doesn’t try to interpret those -i, -j, etc as PowerShell parameters to the Start-Process command. Try this:

Start-Process D:\Application\app.exe -ArgumentList @('-i', $RemoteInstance, '-j', $RemoteJob, '-d', $SQLDomain, '-t', $timeLimit, '-p', $RunMode)

The error went away after the correction, but now the remote program does not execute.

I have tested that the program did execute if I hard coded the parameter values in the script. There is still something not right.

Sorry, that doesn’t really give me anything to go on. When you say it worked when you hard-coded values, what did that code look like?

Dave,

I am sorry. It was my mistake. I had been using the code below to invoke the command; therefore, it did not work.

$Session = New-PSSession -ComputerName $Computer -Credential $Credential
Invoke-Command -ComputerName $Computer -ScriptBlock $scriptBlock -ArgumentList ($RemoteInstance, $RemoteJob, $SQLDomain, $timeLimit, $RunMode)

After I changed the second line of the code to code below, it worked:

$Session = New-PSSession -ComputerName $Computer -Credential $Credential
Invoke-Command -Session $Session -ScriptBlock $scriptBlock -ArgumentList ($RemoteInstance, $RemoteJob, $SQLDomain, $timeLimit, $RunMode)

It appears that PowerShell cannot invoke the command without using the current PS session.

Thank you so much for the help.

One more thing. Currently, the program path for the Start-Process cmdlet in the script block is hard coded in the script.

Is there a way to pass the program path as a parameter to the script block? I tried to set the program path to a variable, and placed the variable in in the script block, and it complained that it could not find the program file.

Thanks.

Sure, no different than passing in all the other variables to the command. You just have to add it to both your param block and the -ArgumentList parameter when calling Invoke-Command.

$scriptBlock = {
    param ($Path, $RemoteInstance, $RemoteJob, $SQLDomain, $timeLimit, $RunMode)
 
    Start-Process $Path -ArgumentList @('-i', $RemoteInstance, '-j', $RemoteJob, '-d', $SQLDomain, '-t', $timeLimit, '-p', $RunMode)
}
 
Invoke-Command -ComputerName $computer -ScriptBlock $scriptBlock -ArgumentList ('D:\Application\app.exe', $RemoteInstance, $RemoteJob, $SQLDomain, $timeLimit, $RunMode)

It looks like I can pass another positional parameter to the from the Invoke-Command cmdlet to the Start-Process cmdl within the script block, and works fine.

Invoke-Command -Session $Session -ScriptBlock $scriptBlock -ArgumentList ($filePath, $RemoteInstance, $RemoteJob, $SQLDomain, $timeLimit, $RunMode)
$scriptBlock = {
    param ($filePath, $RemoteInstance, $RemoteJob, $SQLDomain, $timeLimit, $RunMode)
    Start-Process -FilePath $filePath -ArgumentList @('-i', $RemoteInstance, '-j', $RemoteJob, '-d', $SQLDomain, '-t', $timeLimit, '-p', $RunMode)
}

Thanks again.