Split: Passing Parameters to Invoke-Command

This topic contains 9 replies, has 2 voices, and was last updated by Profile photo of Clum09 Clum09 1 year, 9 months ago.

  • Author
    Posts
  • #22614
    Profile photo of Clum09
    Clum09
    Participant

    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: (:) [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.

  • #22617
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    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)
    
    
  • #22619
    Profile photo of Clum09
    Clum09
    Participant

    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: (:) [Start-Process], ParameterBindingException
    + FullyQualifiedErrorId : AmbiguousParameter,Microsoft.PowerShell.Commands.StartProcessCommand
    + PSComputerName : MYCOMPUTER

  • #22621
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    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)
    
  • #22623
    Profile photo of Clum09
    Clum09
    Participant

    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.

  • #22626
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    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?

  • #22637
    Profile photo of Clum09
    Clum09
    Participant

    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.

  • #22638
    Profile photo of Clum09
    Clum09
    Participant

    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.

  • #22639
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    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)
    
  • #22640
    Profile photo of Clum09
    Clum09
    Participant

    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.

You must be logged in to reply to this topic.