Split: Passing Parameters to Invoke-Command

This topic contains 9 replies, has 2 voices, and was last updated by  Clum09 2 years, 6 months ago.

  • Author
    Posts
  • #22614

    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

    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

    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

    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

    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

    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

    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

    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

    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

    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.