27

In Powershell I am running psftp.exe which is PuTTy's homepage. I am doing this:

$cmd = "psftp.exe"
$args = '"username@ssh"@ftp.domain.com -b psftp.txt';
$output = & $cmd $args

This works; and I am printing out $output. But it only catches some output in that variable (like "Remote working directory is [...]") and is throwing other output to an error type like this:

psftp.exe : Using username "username@ssh".
At C:\full_script.ps1:37 char:20
+         $output = & <<<<  $cmd $args
    + CategoryInfo          : NotSpecified: (Using username "username@ssh".:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

This "Using username ..." etc looks like a normal FTP message. How can I make sure all output gets put into $output?

JBurace
  • 5,123
  • 17
  • 51
  • 76
  • If you have to use the call operator (&), (which you don't if directly running psftp), the args have to be an array, like `'user@domain','-b','file.txt'` – js2010 Oct 05 '22 at 14:39

3 Answers3

23

The problem is some output is being sent to STDERR and redirection works differently in PowerShell than in CMD.EXE.

How to redirect output of console program to a file in PowerShell has a good description of the problem and a clever workaround.

Basically, call CMD with your executable as a parameter. Like this:

UPDATE

I fixed my code so it would actually work. :)

$args = '"username@ssh"@ftp.domain.com -b psftp.txt';
$output = cmd /c psftp.exe $args 2`>`&1
aphoria
  • 19,796
  • 7
  • 64
  • 73
  • No quotes around the $cmd details? I tried this, but the Powershell just seems to hang now. – JBurace Mar 15 '13 at 17:11
  • Thanks, that somewhat worked as it didn't parse any output into an STDERR. But instead of the "Using username ..." etc now being in `$output`, it seems nowhere to be found. With your code, did you intend for that? – JBurace Mar 15 '13 at 17:24
  • I didn't have `PSFTP.EXE` to test with so I was using `PSEXEC.EXE` and `$args = '-d'` to test. I'll see if I can try it with `PSFTP`. – aphoria Mar 15 '13 at 17:28
  • I should add that I was using `PSEXEC` because I know it writes some of it's output to STDERR. – aphoria Mar 15 '13 at 17:29
  • Actually I may be mistaken; I think the STDERR is there. But appears at the end of the $output string. Intended? – JBurace Mar 15 '13 at 17:36
  • It should capture it in the order it is output. Where does it appear if you just run your command from the prompt without redirecting or capturing the output to a variable? – aphoria Mar 15 '13 at 17:38
  • If you use cmd /c, it all goes to standard output anyway. – js2010 Oct 05 '22 at 14:24
13

Give this a try

$output = [string] (& psftp.exe 'username@ssh@ftp.domain.com' -b psftp.txt 2>&1)

There is a PowerShell bug about 2>&1 making error records. The [string] cast works around it.

Andy Arismendi
  • 50,577
  • 16
  • 107
  • 124
1
& "my.exe" | Out-Null    #go nowhere    
& "my.exe" | Out-Default # go to default destination  (e.g. console)
& "my.exe" | Out-String  # return a string

the piping will return it in real-time

& "my.exe" | %{    
   if ($_ -match 'OK')    
   { Write-Host $_ -f Green }    
   else if ($_ -match 'FAIL|ERROR')   
   { Write-Host $_ -f Red }   
   else    
   { Write-Host $_ }    
}

Note: If the executed program returns anything other than a 0 exitcode, the piping will not work. You can force it to pipe with redirection operators such as 2>&1

& "my.exe" 2>&1 | Out-String

sources:

https://stackoverflow.com/a/7272390/254276

https://social.technet.microsoft.com/forums/windowsserver/en-US/b6691fba-0e92-4e9d-aec2-47f3d5a17419/start-process-and-redirect-output-to-powershell-window

tcables
  • 1,231
  • 5
  • 16
  • 36