0

This is my first question on SO so here goes!

I'm getting started with a simple powershell script that I intend to use to benchmark some archiving software. I want to run the archiver (7-zip on Windows 10 in this case) and write the console output to a text file to keep as a log. Then, I want to append to that same log the start time, end time, file sizes... etc.

The problem is I'm having difficulty sending the output to the text file. During multiple tries I never could make it work. I tried Out-File and also the normal ">" redirect but it still ends empty. I even tried setting -PassThru parameter on Start-Process but it only sent the object properties instead of the Host contents.

Curiously, when I make this command run in CMD with the ">" redirect, it works as expected and I find a text file with the expected contents.

This is my current powershell script:

$7zFilePath = "C:\Program Files\7-Zip\7z.exe"
$dateStart = Get-Date
$contentsToArchive = "D:\Temp -Local\Attack on Titan- Before the Fall-002.jpg"
$workingFolder = "D:\Temp"
$archiveName = "testing {0:yyyy-MM-dd hh.mm.ss.ffff}" -f ($dateStart)
$argument = "a -t7z -m0=LZMA2 -mmt=on -mx9 -md=64m -ms=16g -mfb=273 -mqs=on -mtc=on -mta=on -bb3 `"$workingFolder\$archiveName.7z`" `"$contentsToArchive`""
Set-Location $workingFolder
Start-Process -FilePath $7zFilePath -NoNewWindow -ArgumentList $argument | Out-File ".\$archiveName.txt"
Zcehtro
  • 33
  • 1
  • 7
  • 1
    If I understood correctly, you're looking to use the `-RedirectStandardOutput` parameter from `Start-Process` instead of `Out-File` – Santiago Squarzon Mar 20 '22 at 17:59
  • 1
    Oh drat. I wasn't aware of this, but I think I know how it'll play out. I'll give it a try. TYVM! – Zcehtro Mar 20 '22 at 18:08
  • 1
    Basically, all the std out from the started process will be redirected to a file :) – Santiago Squarzon Mar 20 '22 at 18:09
  • 1
    Taking a step back: To synchronously execute console applications or batch files and capture their output, call them _directly_ (`c:\path\to\some.exe ...` or `& $exePath ...`), do _not_ use `Start-Process` (or the `System.Diagnostics.Process` API it is based on) - see [this answer](https://stackoverflow.com/a/51334633/45375). [GitHub docs issue #6239](https://github.com/MicrosoftDocs/PowerShell-Docs/issues/6239) provides guidance on when use of `Start-Process` is and isn't appropriate. – mklement0 Mar 21 '22 at 02:37
  • You've both been a great help. I managed to get it working using both methods. However, I prefer using the `&` method. I'll post an Answer to my own question to close this. – Zcehtro Mar 22 '22 at 18:06

1 Answers1

1

I'm answering my own question because Santiago Squarzon and mklement0 already suggested the solution in the comments to my OP.

Santiago's allowed me to produce the result with Start-Process:

$7zFilePath = "C:\Program Files\7-Zip\7z.exe"
$contentsToArchive = "D:\Temp -Local\Attack on Titan- Before the Fall-002.jpg"
$workingFolder = "D:\Games\Emulation\ROMS\GoodGen V3.21"
$archiveName = "testing {0:yyyy-MM-dd HH.mm.ss.ffff}" -f ($dateStart)

$argument = "a -t7z -m0=LZMA2 -mmt=on -mx9 -md=64m -ms=16g -mfb=273 -mqs=on -mtc=on -mta=on -bb3 `"$workingFolder\$archiveName.7z`" `"$contentsToArchive`""
Set-Location $workingFolder
Start-Process $7zFilePath "$argument" -NoNewWindow -Wait -RedirectStandardOutput ".\$archiveName.txt"

Basically, to use Start-Process and produce a text file with the output I needed to specify it in the -RedirectStandardOutput parameter (which I wasn't using).

However, the output isn't displayed in the Host because it goes straight to the specified text file.

For this, mklement0's explanation and wiki were really useful. Using the & call was much better:

& $7zFilePath `"$argument`" | Out-File -FilePath ".\$archiveName.txt"

With this, I get the output in the Host, and also it's copied to the text file.

Many thanks to you both.

Zcehtro
  • 33
  • 1
  • 7