1
Write-Host "DISM and SFC" -ForegroundColor Cyan
Start-Transcript C:\DISM_SFC.txt
Start-Process -FilePath "dism.exe" -ArgumentList '/online /cleanup-image /analyzecomponentstore' -Wait -NoNewWindow
Start-Process -FilePath "dism.exe" -ArgumentList '/online /cleanup-image /startcomponentcleanup' -Wait -NoNewWindow
Start-Process -FilePath "dism.exe" -ArgumentList '/online /cleanup-image /checkhealth' -Wait -NoNewWindow
Start-Process -FilePath "dism.exe" -ArgumentList '/online /cleanup-image /scanhealth' -Wait -NoNewWindow
Start-Process -FilePath "dism.exe" -ArgumentList '/online /cleanup-image /restorehealth' -Wait -NoNewWindow
Start-Process -FilePath "sfc.exe" -ArgumentList '/scannow' -Wait -NoNewWindow
Stop-Transcript
Write-Host "DISM and SFC completed"`n -ForegroundColor Magenta

I'm trying to add Start-Transcript/Stop-Transcript to my tune-up script and I can't get it to work properly. It performs the commands, creates the text file, but doesn't add the results in the text file.

I think the issue is related to the -NoNewWindow but I'm kind of lost.

Moxadonis
  • 23
  • 4

1 Answers1

1

dism.exe and sfc.exe are console-subsystem Windows applications.

To invoke them synchronously, with their output streams (stdout, stderr) connected to PowerShell's output streams , invoke them directly; e.g.:

dism.exe/online /cleanup-image /analyzecomponentstore
# ...
sfc.exe /scannow

Note:

  • If your executable name or path were quoted or expressed via variable references, you'd need to prepend &, the call operator (e.g., $exe = 'dism.exe'; & $exe ...)

This is the prerequisite for output to show up in your transcripts.

By contrast, if you use Start-Process's -NoNewWindow switch, the program's output prints directly to the console, with no ability to capture it in PowerShell.

An additional advantage of direct, synchronous execution is that the executable's process exit code will be reflected in the automatic $LASTEXITCODE variable


For regular invocations without special requirements - such as wanting to run in a new window, with elevation, or as a different user - Start-Process is usually the wrong tool.

While you can use it to make a call to a GUI(-subsystem) application synchronous (such applications run asynchronously by default), namely with -Wait, a trick allows you to use direct invocation there as well: Pipe to Out-Null (or, in the rare event that your GUI application explicitly attaches to the caller's console and produces output, to Write-Output); e.g.:

# Opens Notepad and waits until it's closed.
Notepad.exe | Out-Null
  • See this answer for more information about this technique.

GitHub docs issue #6239 provides guidance on when use of Start-Process is and isn't appropriate.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • That worked. The reason why I didn't invoke it directly was that on some computers, it would open the command in a new PowerShell window. I'm not sure why sometimes it would work perfectly, and other times it would open a separate window... – Moxadonis Jun 10 '23 at 16:57
  • 1
    Glad to hear it, @Moxadonis. That the commands would sometimes run in a new window is mysterious. – mklement0 Jun 10 '23 at 16:58