Search code examples
powershellazure-pipelinesazure-pipelines-release-pipelinestart-process

start-process : The input object cannot be bound to any parameters for the command


I am adding the Powershell task in the Azure pipeline to start the exe by taking the commands in the pipe and starting the process with two argument lists. Also I have to wait for the exe to load with the argument then pass the command(s). Can we do that without start-process

Here is my script

$exeArguments = "arg1", "arg2"
"command1" | start-process -FilePath myapplication.exe -ArgumentList $exeArguments 

And I am getting the following error

  • start-process : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.

    • CategoryInfo : InvalidArgument: (init-instrument:String) [Start-Process], ParameterBindingException
    • FullyQualifiedErrorId : InputObjectNotBound,Microsoft.PowerShell.Commands.StartProcessCommand

Does the start-process do not take pipe input and arguments at the same time?


Solution

  • No, Start-Process fundamentally does not accept pipeline input, as JosefZ notes.

    Instead, you must use the -RedirectStandardInput parameter, to which you must pass the path of a (possibly temporary) file containing the data you want to send to the target process' stdin (standard input) stream.


    Here's a simple (contrived example):

    # Create a temporary file...
    $tempFile = New-TemporaryFile
    # ... and fill it with sample data.
    @'
    hi
    there
    '@ | Set-Content $tempFile
    
    # "Pipe" the file's content to `findstr.exe hi`, i.e. send it
    # to the latter's stdin stream.
    # This will print 'hi', i.e. the matching line to the console.
    Start-Process -Wait -NoNewWindow -RedirectStandardInput $tempFile -FilePath findstr.exe -ArgumentList hi 
    
    # Clean up.
    $tempFile | Remove-Item
    

    Note that, similarly, you cannot directly capture output from a Start-Process-launched process in PowerShell's pipeline, and must use -RedirectStandardOutput and -RedirectStandardError to send the output to files.

    (In the sample command above, -NoNewWindow ensures that the process' output prints to the console, however, it cannot be captured.)


    Taking a step back:

    • If myapplication.exe is a console (terminal-based) application, and your intent is to execute it synchronously in the current console (terminal), there is no need to use Start-Process - just call it directly, in which case you can provide stdin input directly via the pipeline:[1]

      $exeArguments = "arg1", "arg2"
      "command1" | myapplication.exe @exeArguments 
      
    • See this answer for details and this guidance for when use of Start-Process is and isn't appropriate.


    [1] Note that it is the value of the $OutputEncoding preference variable that controls the character encoding PowerShell uses for the data being sent to an external application (invariably as text up to PowerShell 7.3.x; in 7.4+, sending arbitrary [byte]s is now supported). Complementarily, it is the value of [Console]::OutputEncoding that determines how PowerShell decodes data received from an external application's stdout and stderr streams.
    See this answer for more information.