2

I have a PowerShell script where I use Start-Process and redirect output to a log file. The cmd is in a for loop, and I'd like to have the output append each time it runs. Right now it wipes out the log file each time it runs. Is there a way to redirect and append?

Start-Process $cmd -ArgumentList $cmdArgs -RedirectStandardError $logFile -Wait -NoNewWindow
Bassie
  • 9,529
  • 8
  • 68
  • 159
Paul Wasserman
  • 137
  • 2
  • 13

3 Answers3

2

Note: To synchronously execute console applications, call them directly (c:\path\to\some.exe ... or & $exePath ...), do not use Start-Process - see this answer; that way, you can capture their output directly with $ouput = c:\path\to\some.exe ... or append their output to an existing file with >> or by piping to Add-Content[1] - see about_Redirection

  • Use redirection 2>&1 in combination with >> $logFile to also capture standard error output, along with standard output.
& $cmd $cmdArgs 2>&1 >> $logFile
  • Use redirection 2>> $logFile to capture only standard error output.
& $cmd $cmdArgs 2>> $logFile

The rest of this answer addresses the question as asked:


No, (as of PowerShell 7.0) there's no way to append to preexisting files with Start-Process'
-RedirectStandardOutput and -RedirectStandardError parameters
- they invariably replace the specified output files.

This answer shows how to use the underlying .NET API directly, allowing you to collect the process' output in memory, which then allows you to append that to an existing file (e.g., with
Add-Content).

However, as your own answer shows, using an auxiliary temporary file with
-RedirectStandardError, whose content is later appended to the overall output file is probably the simplest solution.


[1] >> blindly applies Out-File's default encoding, which is UTF-16LE ("Unicode") in Windows PowerShell, and BOM-less UTF-8 in PowerShell [Core] 6+; Add-Content, by contrast, tries to match the target file's preeexisting encoding.

mklement0
  • 382,024
  • 64
  • 607
  • 775
2

Thank you all for your responses. I decided to go with my own alternative, which was to send the output from each Start-Process job to a temporary log file, and then copy the data from the temp log file into my primary log file. Not nearly as elegant, but simple enough and it works.

$logFile = "C:\work\myLogFile.log"
$logFileTemp = "C:\work\myTempLogFile.log"
Start-Process $cmd -ArgumentList $cmdArgs -RedirectStandardError $logFileTemp -Wait -NoNewWindow
Get-Content $logFileTemp | Out-File $logFile -Append
mklement0
  • 382,024
  • 64
  • 607
  • 775
Paul Wasserman
  • 137
  • 2
  • 13
1

If you can get away with just calling the cmd directly, you can try with 2>>:

&$cmd 2>> $logFile

See SS64 for more details:

command 2>> filename # APPEND errors to a file

Bassie
  • 9,529
  • 8
  • 68
  • 159