
close
close
I hope you’ve enjoyed our journey into displaying domain controller service statuses in a more colorful format. I hope you have been thinking about how you could extend the techniques I’ve shown you into more flexible and re-usable tools. You will want to be caught up on the previous articles or some of what I’m about to show you might be confusing.
I’m sure you can think of a number of commands where you would like to highlight a particular value. In this article, I want to end up with a PowerShell function that will get the job done. Once again, let’s start with a set of domain controllers and services.
$dcs = "chi-dc01","chi-dc02","chi-dc04" $svcs = "adws","dns","kdc","netlogon"
Depending on the service status, I want to display it in a given console color based on a hashtable.
$keycolor = @{ Stopped = "Red" Running = "Green" StartPending = "Magenta" ContinuePending = "Cyan" StopPending = "Magenta" PausePending = "Cyan" Paused = "Yellow" }
I’m also going to need a regular expression pattern to match on the output.
[regex]$r = $keycolor.keys -join "|"
When building a tool, remember to break things down into discrete steps so that you can modularize. I’ll save the data separately.
$data = Get-Service -name $svcs -computername $dcs
This makes it easier to revise my code that will handle the formatting, and I won’t have to rerun the command all the time. I know from the previous articles that I need to turn the data into an array of strings. I had been using the Split() method, but it is just as easy to use the Split operator.
$in = ($data |Select Status,Displayname,Machinename | Out-String) -split "`n"
Now I can pipe this to the code I had been using with ForEach-Object.
$in | foreach { $z = $r.Match($_) if ($z.success) { [string]$m = $z.Value Write-Host $_.Substring(0,$z.index) -NoNewline Write-Host $_.Substring($z.Index,$z.Length) -ForegroundColor $keycolor.item($m) -NoNewline Write-Host $_.Substring($z.index+$z.Length) } else { #just write the line Write-Host $_ } }
Highlighted output (Image Credit: Jeff Hicks)
Function Out-Highlight { [cmdletbinding()] Param( [Parameter(Position=0,Mandatory,ValueFromPipeline)] [string]$Line ) Begin { $keycolor = @{ Stopped = "Red" Running = "Green" StartPending = "Magenta" ContinuePending = "Cyan" StopPending = "Magenta" PausePending = "Cyan" Paused = "Yellow" } [regex]$r = $keycolor.keys -join "|" } Process { $z = $r.Match($Line) if ($z.success) { [string]$m = $z.Value Write-Host $Line.Substring(0,$z.index) -NoNewline Write-Host $line.Substring($z.Index,$z.Length) -ForegroundColor $keycolor.item($m) -NoNewline Write-Host $line.Substring($z.index+$z.Length) } else { #just write the line Write-Host $line } } End { #not used } } #end function
And it more or less works.
Testing the prototype function (Image Credit: Jeff Hicks)
Function Out-Highlight { [cmdletbinding()] Param( [Parameter( Position = 0, Mandatory, ValueFromPipeline )] [object]$InputObject, [Parameter(Mandatory,HelpMessage="Enter a hashtable of associated property names and console colors")] [ValidateNotNullorEmpty()] [hashtable]$Highlight, [Parameter(HelpMessage="Enter a regular expression pattern")] [ValidateNotNullorEmpty()] [Alias("rx")] [regex]$Expression = ".*", [Switch]$Background, [switch]$Line ) Begin { Write-Verbose "Starting: $($MyInvocation.Mycommand)" #initialize an array to hold incoming data $data = @() } #begin Process { $data +=$InputObject } #process End { #convert the data to an array of strings ($data | out-string) -split "`n" | foreach { $rxtest = $Expression.Match($_) if ($rxtest.success) { #get the matched value and trim off extra spaces [string]$mtch = $rxtest.Value.Trim() #get corresponding color from key hash [string]$item = ($highlight.keys).where({$mtch -match "$_$"}) if ($Line) { $paramHash = @{ Object = $_ } if ($Background) { $paramHash.BackgroundColor = $Highlight.item($item) } else { $paramHash.foregroundColor = $Highlight.item($item) } #Write the highlighted portion of the line Write-Host @paramHash } else { Write-Host $_.Substring(0,$rxtest.index) -NoNewline #define a hashtable of parameters to splat to Write-Host $paramHash = @{ Object = $_.Substring($rxtest.Index,$rxtest.Length) NoNewLine = $True } if ($Background) { $paramHash.BackgroundColor = $Highlight.item($item) } else { $paramHash.foregroundColor = $Highlight.item($item) } #Write the highlighted portion of the line Write-Host @paramHash #write the rest of the line Write-Host $_.Substring($rxtest.index+$rxtest.Length) } } #if rxtest is successful else { #just write the line Write-Host $_ } } #foreach Write-Verbose "Ending: $($MyInvocation.Mycommand)" } #end } #end function
This version lacks any sort of help documentation, but you can see the syntax:
Out-Highlight syntax (Image Credit: Jeff Hicks)
Testing the function (Image Credit: Jeff Hicks)
Highlighting an entire line (Image Credit: Jeff Hicks)
dir c:\work -file | Out-Highlight -Highlight @{ps1 = "red";png = "cyan";bat = "magenta";xml = "yellow"} -Expression "(?<=\d)(([\s])\S+)+\.(png|ps1|bat|xml)" -Line
Highlighting files (Image Credit: Jeff Hicks)
get-vm | Out-Highlight -Highlight @{Running = "Green"; Saved = "Magenta";Paused = "Cyan";Off="Yellow";Critical = "Red"} -Expression "\b(Running|Saved|Off|Paused|\w+Critical)\b"
Highlighting virtual machines (Image Credit: Jeff Hicks)
More in PowerShell
Most popular on petri