stej
stej

Reputation: 29479

Output redirection still with colors in PowerShell

Suppose I run msbuild like this:

function Clean-Sln {
    param($sln)
    MSBuild.exe $sln /target:Clean
}
Clean-Sln c:\temp\SO.sln

In Posh console the output is in colors. That's pretty handy - you spot colors just by watching the output. And e.g. not important messages are grey.

Question

I'd like to add ability to redirect it somewhere like this (simplified example):

function Clean-Sln {
    param($sln)
    MSBuild.exe $sln /target:Clean | Redirect-AccordingToRedirectionVariable
}
$global:Redirection = 'Console'
Clean-Sln c:\temp\SO.sln
$global:Redirection = 'TempFile'
Clean-Sln c:\temp\Another.sln

Is it even possible? I guess it is not :| Or do you have any advice how to achieve the goal?

Possible solution:

if ($Redirection -eq 'Console) {
  MSBuild.exe $sln /target:Clean | Redirect-AccordingToRedirectionVariable
} else {
  MSBuild.exe $sln /target:Clean | Out-File c:\temp.txt  
}

But if you imagine there can be many many msbuild calls, it's not ideal.

Don't be shy to tell me any new suggestion how to cope with it ;)


Any background info about redirections/coloring/outpu is welcome as well.
(The problem is not msbuild specific, the problem touches any application that writes colored output)

Upvotes: 4

Views: 1989

Answers (1)

Keith Hill
Keith Hill

Reputation: 202052

Yeah I would avoid piping colored output. At that point, AFAICT, all color info is lost. I would recommend using the /filelogger and /noconsolelogger parameters on MSBuild e.g.:

function Invoke-MSBuild($project, [string[]]$targets, [switch]$logToFile) {
    $OFS = ';'
    $targetArg = if ($targets) {"/t:$targets"} else {''}
    if ($logToFile) {
        msbuild.exe $project $targetArg  /filelogger /noconsolelogger
    }
    else {
        msbuild.exe $project $targetArg 
    }
}

or you could do something even simpler like this:

function Invoke-MSBuild($project, [string[]]$targets, $logFile) {
    $OFS = ';'
    $targetArg = if ($targets) {"/t:$targets"} else {''}
    if ($logFile) {
        msbuild.exe $project $targetArg > $logFile
    }
    else {
        msbuild.exe $project $targetArg 
    }
}

Upvotes: 3

Related Questions