PowerShell format-table with $Host.UI.RawUI.ForegroundColor issues

Good morning,

I am having an issue colorizing within format-table using an expression and $Host.UI.RawUI.ForegroundColor.  I populated an array using garbage populated data and it works great:

$arrNetVirtLookupRecords = @()
100..150|%{
	$objNetVirtLookupRecord = $null
	$objNetVirtLookupRecord = New-Object PSObject -Property @{
		VMHost = $null;
		VSID = $null;
		VMName = $null;
		CustomerAddress = $null;
		ProviderAddress = $null;
		CustomerMAC = $null;
	}
	$objNetVirtLookupRecord.VMHost = If($_ % 2 -eq 0){"server101"} Else{"server102"}
	$objNetVirtLookupRecord.VSID = "1234567"
	$objNetVirtLookupRecord.VMName = "WINDOWS$_"
	$objNetVirtLookupRecord.CustomerAddress = "192.168.1.$_"
	$objNetVirtLookupRecord.ProviderAddress = "192.168.1.$_"
	$objNetVirtLookupRecord.CustomerMAC = "000000000$_"
	$arrNetVirtLookupRecords += $objNetVirtLookupRecord
}

$objOriginalColor = $Host.UI.RawUI.ForegroundColor
$arrNetVirtLookupRecords | Sort-Object VMHost, VMName | Format-Table @{
	Name="VMHost"
	Expression={
		If($_.VMHost -eq 'server102'){$Host.ui.rawui.ForegroundColor = "cyan"; $_.VMHost}
		Else{$Host.UI.RawUI.ForegroundColor = $objOriginalColor; $_.VMHost}
	}
}, VSID, VMName, CustomerAddress, ProviderAddress, CustomerMAC
$Host.UI.RawUI.ForegroundColor = $objOriginalColor

Open in new window


However when I run it against the real data it does not change the color.  When I run it against the real data and change the script to:

$objOriginalColor = $Host.UI.RawUI.ForegroundColor
$arrNetVirtLookupRecords | Sort-Object VMHost, VMName | Format-Table @{
	Name="VMHost"
	Expression={
		If("$($_.VMHost)" -eq 'server101'){$Host.ui.rawui.ForegroundColor = "cyan"; "Match)"}
		Else{$Host.UI.RawUI.ForegroundColor = $objOriginalColor; "No Match"}
	}
}, VSID, VMName, CustomerAddress, ProviderAddress, CustomerMAC
$Host.UI.RawUI.ForegroundColor = $objOriginalColor

Open in new window


Match and No Match are populated in the field appropriately but the color doesn't change.  Also if I print out the $Host.UI.RawUI.ForegroundColor in the expression it displays what the color should be, but the console doesn't display it.

Thanks for any assistance!
omnipower321Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

 
footechCommented:
You're not running in the ISE are you?  That behaves different than a console.
0
 
omnipower321Author Commented:
I am not.  Straight up console.
0
 
footechCommented:
I might have gotten somewhere with this.
What version of PS are you running?  Are you running everything on the same machine?

What I saw was with PS 5.0 that the color used was whatever the first object displayed used.  So if the first object was set to be cyan, then everything that followed was too.  With PS 4.0 the color changed according to the match.  I believe this is due to the change in PS 5.0 as to how Format-Table works.  If I changed the command to Format-List I observed the color change.

◦When you use the Format-Table command, table columns are now automatically formatted by evaluating the first 300ms of data that passes through the stream.
0
Making Bulk Changes to Active Directory

Watch this video to see how easy it is to make mass changes to Active Directory from an external text file without using complicated scripts.

 
omnipower321Author Commented:
Thank you for the responses!  I am running these 2 tests from the same machine and am using PowerShell version 4.

I get the same behavior with Format-List:
$objOriginalColor = $Host.UI.RawUI.ForegroundColor
$arrNetVirtLookupRecords | Sort-Object VMHost, VMName | Format-List @{
	Name="VMHost"
	Expression={
		If("$($_.VMHost)" -eq 'server101'){$Host.ui.rawui.ForegroundColor = "cyan"; "$($_.VMHost) $($Host.UI.RawUI.ForegroundColor)"}
		Else{$Host.UI.RawUI.ForegroundColor = $objOriginalColor; "$($_.VMHost) $($Host.UI.RawUI.ForegroundColor)"}
	}
}, VSID, VMName, CustomerAddress, ProviderAddress, CustomerMAC
$Host.UI.RawUI.ForegroundColor = $objOriginalColor

Open in new window



VMHost          : server101 Cyan
VSID            : 1234567
VMName          : WINDOWS101
CustomerAddress : 192.168.1.x
ProviderAddress : 192.168.1.x
CustomerMAC     : 00000000101

VMHost          : server102 DarkYellow
VSID            : 1234567
VMName          : WINDOWS102
CustomerAddress : 192.168.1.x
ProviderAddress : 192.168.1.x
CustomerMAC     : 0000000000102

But the console color never changes.
0
 
oBdACommented:
For the fun of it, here's a function. It expects an additional property '__Color' containing a hashtable with the fore- and/or background color the respective line should have (this hashtable will be splatted and used as argument for Write-Host).
-AutoSize and -HideTableHeaders are supported, and it works in the ISE as well.
Function Format-TableColored {
[CmdletBinding()]
Param(
	[Parameter(ValueFromPipeline=$true, Position=0)]
	[PSObject]$InputObject,
	[Switch]$AutoSize,
	[Switch]$HideTableHeaders,
	[String]$ColorProperty = "__Color"
)
	Begin {
		$Output = @()
		$Colors = @()
		$FirstValue = ''
		$StartColor = $False
		$ColorArgs = @{}
	}
	Process {
		If (!$FirstValue) {$FirstValue = [regex]::Escape(($InputObject.psobject.Properties | Select-Object -ExpandProperty Value -First 1))}
		$Colors += If ($InputObject.$ColorProperty -is [hashtable]) {$InputObject.$ColorProperty} Else {@{}}
		$Output += $InputObject | Select-Object -Property * -ExcludeProperty $ColorProperty
	}
	End {
		[void]$PSBoundParameters.Remove('ColorProperty')
		$PSBoundParameters['InputObject'] = $Output
		$i = 0
		(Format-Table @PSBoundParameters | Out-String) -split "`r`n" | ForEach-Object {
			If (!$StartColor -and ($_ -match "\s*$($FirstValue)")) {$StartColor = $True}
			If ($StartColor -and $_) {
				$ColorArgs = $Colors[$i++]
			} Else {
				$ColorArgs.Clear()
			}
			Write-Host -Object $_ @ColorArgs
		}
	}
}

Open in new window

Sample call:
Get-ChildItem C:\Windows\*.exe |
	Select-Object -Property `
		Name,
		Extension,
		LastWriteTime,
		@{Name='__Color'; Expression={
			Switch ($_.BaseName) {
				'Explorer'	{@{Fore='Black';Back='Yellow'}}
				'regedit'	{@{Back='Blue';Fore='White;}}
				'notepad'	{@{Back='DarkGray'}}
				'write'		{@{Fore='Magenta'}}
			}
		}} |
	Format-TableColored -AutoSize

Open in new window

In your case, this should work:
$arrNetVirtLookupRecords |
	Select-Object VMHost, VSID, VMName, CustomerAddress, ProviderAddress, CustomerMAC, @{Name='__Color'; Expression={If ($_.VMHost -eq 'server101') {@{Fore='Cyan'}}}} |
	Sort-Object VMHost, VMName | Format-TableColored

Open in new window

1

Experts Exchange Solution brought to you by ConnectWise

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
 
footechCommented:
Sorry, I can't think of any possible cause, unless there's a clue in the actual code you're running to gather data (but it seems unlikely).

One option which I found works with PS 5.0 (just using test data), is to specify the -GroupBy parameter of Format-Table.  However, if that that won't work for you, given what I found with PS 5.0, I'd pursue another route if I were you.  It doesn't seem to be a great idea to design something that will break when run on a new version of PS.
0
 
footechCommented:
@oBdA - I like what you did with your function.  I was thinking about Format-Table > Out-String > Write-Host as an alternative but hadn't fleshed it out yet.
0
 
omnipower321Author Commented:
The function worked like a charm!  Thanks a bunch footech and oBdA.

I was going down a nasty path of Write-Hosts that was far less elegant.
0
 
omnipower321Author Commented:
Thanks again for all of the help!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.