I'm writing a PowerShell script to msbuild
a bunch of solutions. I want to count how many solutions build successfully and how many fail. I also want to see the compiler errors, but only from the first one that fails (I'm assuming the others will usually have similar errors and I don't want to clutter my output).
My question is about how to run an external command (msbuild
in this case), but conditionally pipe its output. If I'm running it and haven't gotten any failures yet, I don't want to pipe its output; I want it to output directly to the console, with no redirection, so it will color-code its output. (Like many programs, msbuild turns off color-coding if it sees that its stdout is redirected.) But if I have gotten failures before, I want to pipe to Out-Null
.
Obviously I could do this:
if ($SolutionsWithErrors -eq 0) {
msbuild $Path /nologo /v:q /consoleloggerparameters:ErrorsOnly
} else {
msbuild $Path /nologo /v:q /consoleloggerparameters:ErrorsOnly | Out-Null
}
But it seems like there's got to be a way to do it without the duplication. (Okay, it doesn't have to be duplication -- I could leave off /consoleloggerparameters
if I'm piping to null anyway -- but you get the idea.)
There may be other ways to solve this, but for today, I specifically want to know: is there a way to run a command, but only pipe its output if a certain condition is met (and otherwise not pipe it or redirect its output at all, so it can do fancy stuff like color-coded output)?
You can define the output command as a variable and use either Out-Default
or Out-Null
:
# set the output command depending on the condition
$output = if ($SolutionsWithErrors -eq 0) {'Out-Default'} else {'Out-Null'}
# invoke the command with the variable output
msbuild $Path /nologo /v:q /consoleloggerparameters:ErrorsOnly | & $output
UPDATE
The above code loses MSBuild colors. In order to preserve colors and yet avoid duplication of code this approach can be used:
# define the command once as a script block
$command = {msbuild $Path /nologo /v:q /consoleloggerparameters:ErrorsOnly}
# invoke the command with output depending on the condition
if ($SolutionsWithErrors -eq 0) {& $command} else {& $command | Out-Null}
is there a way to run a command, but only pipe its output if a certain condition is met (and otherwise not pipe it or redirect its output at all, so it can do fancy stuff like color-coded output)?
There is no such a way built-in, more likely. But it can be implemented with a function and the function is reused as such a way:
function Invoke-WithOutput($OutputCondition, $Command) {
if ($OutputCondition) { & $Command } else { $null = & $Command }
}
Invoke-WithOutput ($SolutionsWithErrors -eq 0) {
msbuild $Path /nologo /v:q /consoleloggerparameters:ErrorsOnly
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With