5

Here's a sample powershell script:

$in = read-host -prompt "input"
write-host $in

Here's a sample 'test.txt' file:

hello

And we want to pass piped input to it from powershell. Here's some I have tried:

.\test.ps1 < test.txt
.\test.ps1 < .\test.txt
.\test.ps1 | test.txt
.\test.ps1 | .\test.txt
test.txt | .\test.ps1
.\test.txt | .\test.ps1
get-content .\test.txt | .\test.ps1

even just trying to echo input doesn't work either:

echo hi | \.test.ps1

Every example above that doesn't produce an error always prompts the user instead of accepting the piped input.

Note: My powershell version table says 4.0.-1.-1

Thanks

Edit/Result: To those looking for a solution, you cannot pipe input to a powershell script. You have to update your PS file. See the snippets below.

4 Answers 4

5

You can't pipe input to Read-Host, but there should be no need to do so.

PowerShell doesn't support input redirection (<) yet. In practice this is not a (significant) limitation because a < b can be rewritten as b | a (i.e., send output of b as input to a).

PowerShell can prompt for input for a parameter if the parameter's value is missing and it is set as a mandatory attribute. For example:

function test {
  param(
    [parameter(Mandatory=$true)] [String] $TheValue
  )
  "You entered: $TheValue"
}

If you don't provide input for the $TheValue parameter, PowerShell will prompt for it.

In addition, you can specify that a parameter accepts pipeline input. Example:

function test {
  param(
    [parameter(ValueFromPipeline=$true)] [String] $TheValue
  )
  process {
    foreach ( $item in $TheValue ) {
      "Input: $item"
    }
  }
}

So if you write

"A","B","C" | test

The function will output the following:

Input: A
Input: B
Input: C

All of this is spelled out pretty concisely in the PowerShell documentation.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for the snippets. I agree on the 'no need to do so', but in some certain cases we have a powershell file that we don't want to update, because that would cause QA to need to re-certify it. Such is life.
< doesn't work in PowerShell for input redirection, so you don't really have a choice on that.
a < b and b | a are not equivalent in any shell scripting syntax i know of. Do you mean something like cat b | a or TYPE b | a?
Read it more generically. a < b (i.e., use content or output of b as input for a) is functionally equivalent to b | a (i.e., use content or output of b as input for a).
Ugh, in practice, this is not true that "you shouldn't need to". Take for example: PS C:\> diff.exe -ayl <(Write-Output ($OriginalObject | Convert-JSON -Depth 99)) <(Write-Output ($UpdatedObject | ConvertTo-JSON -Depth 99)), where Write-Output here is analogous to echo (echo is an Alias for Write-Output). This doesn't work because stdin redirection is not possible, but this is a common thing that can be d one in *nix shells such as bash.
|
4

The issue is that your script \.test.ps1 is not expecting the value.

Try this:

param(
    [parameter(ValueFromPipeline)]$string
)

# Edit: added if statement
if($string){
    $in = "$string"
}else{
    $in = read-host -prompt "input"
}

Write-Host $in

Alternatively, you can use the magic variable $input without a param part (I don't fully understand this so can't really recommend it):

Write-Host $input

5 Comments

So one would have to edit the PS1 file to support piped input. Is there no way to redirect the standard input? For example, in C# you can simply Console.ReadLine() and you can pipe to that through CMD. You won't be passing any parameters to the executable, you would be redirecting input.
@Peanut there may be a way to get what you're after that's beyond the scope of my knowledge. The Read-Host documentation specifies that it does not accept values from the pipeline. To get the functionality you're after, I would use an if statement. To redirect input to PowerShell, I believe there needs to be something aside from Read-Host in the script
thanks for looking into it. I didn't see the huge note stating "You cannot pipe input to this cmdlet."
Just use $input -- If you put Write-Host $input in your script, it will literally print System.Collections.ArrayList+ArrayListEnumeratorSimple
$input works if you are piping input to .test.ps1, but if you just run $ .test.ps1 from the shell it won't prompt for you to type anything the way that $ cat will.
2

Yes; in Powershell 5.1 "<" is not implemented (which sucks)

so, this won't work: tenkeyf < c:\users\marcus\work\data.num

but,

this will: type c:\users\marcus\work\data.num | tenkeyf

...

1 Comment

...which is exactly what I already wrote in my answer.
0

PowerShell doesn’t have a redirection mechanism, but.NET have.

you can use [System.Diagnostics.Process] implements the purpose of redirecting input.

The relevant Microsoft documents are as follows.

Process Class

This is a sample program that works perfectly on my windows 10 computer

function RunAndInput{
    $pi = [System.Diagnostics.ProcessStartInfo]::new()
    $pi.FileName ="powershell"
    $pi.Arguments = """$PSScriptRoot\receiver.ps1"""
    $pi.UseShellExecute = $false
    $pi.RedirectStandardInput = $true
    $pi.RedirectStandardOutput = $true

    $p = [System.Diagnostics.Process]::Start($pi)

    $p.StandardInput.WriteLine("abc"+ "`r`n");
    $p.StandardOutput.ReadToEnd()
    $p.Kill()
}

RunAndInput

# OutPut

Please enter the information: abc
Received:abc

# receiver.ps1
('Received:' + (Read-Host -Prompt 'Please enter the information'))

Hope to help you!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.