My problem is that I want to Start-Process a powershell file, execute.ps1, that would execute several sql commands then log the outputs in a text file. So far, all the other approaches like start-transcript or *>> just writes the console outputs but not the sql PRINTS. The only thing currently working is -RedirectStandardOutput.
Start-Process powershell "& .\execute.ps1 -dbserver $server -databasename $database -client $client" -RedirectStandardOutput ".\output\$client.txt
However, when I use this, it redirects everything to the txt file leaving the powershell console blank.
Is it possible to display it both in the console and the txt file?
No. However...
Using
ForEach-Objectto write output to console and append to a fileYou may be able to work around it with a
Foreach-Objectloop if the sole reason you are redirecting output is to drop it in a file for later processing. However, you won't be able to useStart-Processto control the location of the output:If you need to use
Start-Processhowever, for example:Then you are out of luck.
Start-Processonly allows you to redirect input and output streams from and to files, respectively.Using
[Process]::Startto display output as the program runs while redirectingThere is a solution to be had if you call
[Process]::Start(StartInfo)yourself, but this is going to be the most advanced solution, and have the most code involved. But, if you find that you needStart-Processand also want the output to be displayed as the program runs, and not just once the child process ends, I would invite you to take a look at this question of mine. The question is ultimately looking to process lines of output asynchronously using process object started with[Process]::Start(StartInfo).Rather than reiterate those solutions here, the answers I would direct you to focus on are @mklement0's and @HAL9256's, although @Cpt.Whale's answer using
Start-JobandReceive-Jobmight work for your needs as well if you don't need to process each line as they are written. In your case, "processing the output asynchronously" just means you want to output the line of output to the Success stream, then append the line to your output file (as shown in the earlierForEach-Objectloop example).If displaying the output can wait until the child process completes
If you don't care that the program emits its output until after it finishes running, you can look at my synchronous implementation in my other question itself which should simplify things a bit.
Even more simply, use
Start-Process -Wait -RedirectStandardOutput FILEand runGet-Contentagainst theRedirectStandardOutputfile path you chose once the process is done executing.Making errors output a different color
Regardless of how you launch the process and perform STDOUT/STDERR redirection, if you want the error information to be in a different color, just read from the error text and use
Write-Hostto change the color:Keep in mind that this in no way retains the original color information. However, it will write anything that was written to STDERR in Red (or any other color you choose). That said, also keep in mind that not all programs use STDERR for error information. Some use STDOUT to emit error information (perhaps erroneously), and others may use STDERR for other information such as verbose, debug, or trace output.
There isn't a one-size-fits-all workaround here, since programs are not required to (and may have good reason not to in some cases) adhere to standards and best practices.