Is there a way to specify a font color when using write-output

前端 未结 5 1581
抹茶落季
抹茶落季 2021-02-07 02:25

I have a powershell script that gives some status output via write-output. I am intentionally not using write-host because the output may be captured and writt

相关标签:
5条回答
  • 2021-02-07 02:42

    This way:

    function Green
    {
        process { Write-Host $_ -ForegroundColor Green }
    }
    
    function Red
    {
        process { Write-Host $_ -ForegroundColor Red }
    }
    
    Write-Output "this is a test" | Green
    Write-Output "this is a test" | Red
    

    0 讨论(0)
  • 2021-02-07 02:46

    I had the same problem, so I share my solution which I think works quite well:

    Write-ColorOutput "Hello" Green Black -NoNewLine
    Write-ColorOutput " World" Red
    

    This is the Cmdlet to use it

    function Write-ColorOutput
    {
        [CmdletBinding()]
        Param(
             [Parameter(Mandatory=$False,Position=1,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)][Object] $Object,
             [Parameter(Mandatory=$False,Position=2,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)][ConsoleColor] $ForegroundColor,
             [Parameter(Mandatory=$False,Position=3,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)][ConsoleColor] $BackgroundColor,
             [Switch]$NoNewline
        )    
    
        # Save previous colors
        $previousForegroundColor = $host.UI.RawUI.ForegroundColor
        $previousBackgroundColor = $host.UI.RawUI.BackgroundColor
    
        # Set BackgroundColor if available
        if($BackgroundColor -ne $null)
        { 
           $host.UI.RawUI.BackgroundColor = $BackgroundColor
        }
    
        # Set $ForegroundColor if available
        if($ForegroundColor -ne $null)
        {
            $host.UI.RawUI.ForegroundColor = $ForegroundColor
        }
    
        # Always write (if we want just a NewLine)
        if($Object -eq $null)
        {
            $Object = ""
        }
    
        if($NoNewline)
        {
            [Console]::Write($Object)
        }
        else
        {
            Write-Output $Object
        }
    
        # Restore previous colors
        $host.UI.RawUI.ForegroundColor = $previousForegroundColor
        $host.UI.RawUI.BackgroundColor = $previousBackgroundColor
    }
    
    0 讨论(0)
  • 2021-02-07 02:55

    I have tried this extra function and it basically works fine:

    function Write-ColorOutput($ForegroundColor)
    {
        # save the current color
        $fc = $host.UI.RawUI.ForegroundColor
    
        # set the new color
        $host.UI.RawUI.ForegroundColor = $ForegroundColor
    
        # output
        if ($args) {
            Write-Output $args
        }
        else {
            $input | Write-Output
        }
    
        # restore the original color
        $host.UI.RawUI.ForegroundColor = $fc
    }
    
    # test
    Write-ColorOutput red (ls)
    Write-ColorOutput green (ls)
    ls | Write-ColorOutput yellow
    

    The result of this particular test is a little bit funny though: we really get lines in red, green and yellow but the table header is in red, i.e. the color of the the first call of the function.

    0 讨论(0)
  • 2021-02-07 02:55

    Separate the results on the pipeline from the status messages in the console.

    E.g., use a function like this in your script:

    function write-status( $status ){
       $status | write-host -fore green -back red;  #send a status msg to the console
       $status | write-output; #send a status object down the pipe
    }
    

    I would also recommend you use one of the following cmdlets over write-host for outputting status messages from your scripts:

    • write-debug
    • write-error
    • write-verbose
    • write-warning

    The appearance of these status messages will vary depending on the cmdlet used. In addition, the user can disable specific levels of status using the $(warning|error|verbose|debug)preference variables, or capture specific status messages using the -(warning|error|verbose|debug)variable common cmdlet parameters.

    0 讨论(0)
  • 2021-02-07 02:58

    I know this post is ancient, but this could come handy to someone out there.

    I wanted to change colors and the accepted answer was not the best solution. In my eyes, the following code is better solution as it takes advantage of the native PowerShell functionality:

    EDIT:

    # Print User message using String Array $message
    function PrintMessageToUser {
        param(
            [Parameter( `
                Mandatory=$True, `
                Valuefrompipeline = $true)]
            [String]$message
        )
        begin {
            $window_private_data = (Get-Host).PrivateData;
            # saving the original colors
            $saved_background_color = $window_private_data.VerboseBackgroundColor
            $saved_foreground_color = $window_private_data.VerboseForegroundColor
            # setting the new colors
            $window_private_data.VerboseBackgroundColor = 'Black';
            $window_private_data.VerboseForegroundColor = 'Red';
        }
        process {
            foreach ($Message in $Message) {
                # Write-Host Considered Harmful - see http://www.jsnover.com/blog/2013/12/07/write-host-considered-harmful/
                # first way how to correctly write it
                #Write-host $message;
                Write-Verbose -Message $message -Verbose;
                # second correct way how to write it
                #$VerbosePreference = "Continue"
                #Write-Verbose $Message;
            }
        }
        end {
          $window_private_data.VerboseBackgroundColor = $saved_background_color;
          $window_private_data.VerboseForegroundColor = $saved_foreground_color;
        }
    
    } # end PrintMessageToUser
    
    0 讨论(0)
提交回复
热议问题