
close
close
Recently, I demonstrated how to bend the rules a bit in PowerShell to provide useful color coding for your PowerShell commands. Although I’d normally encourage you to think about objects in the pipeline, playing with text sometimes fits the bill and can even be a little fun. If you missed the previous articles, take a few minutes to get caught up.
I’ve been using PowerShell commands to check the status of critical services on my domain controllers. To further demonstrate what you can do, I’d like to be able to have services in statuses other than running or stopped. Since we’re dealing with text, I can be creative. I saved the results of my PowerShell command to get services to a text file and manually changed some of the statuses. I’ll bring that file into my PowerShell session.
advertisment
$split = get-content C:\work\testservices.txt
A text array of service data (Image Credit: Jeff Hicks)
foreach ($line in $split) { #append some space after the line [email protected]{Object=" "} Write-Host "$line " -NoNewline #look at the line and add a parameter based on the results #of a regular expression match switch -Regex ($line) { "Stopped" { $params.BackgroundColor = "Red" } "Running" { $params.BackgroundColor = "DarkGreen" } "Pending" { $params.BackgroundColor = "Magenta" } "Paused" { $params.BackgroundColor = "Yellow" } } #write the line with the splatted parameters Write-Host @params } #close foreach
Services with a stop light indicator (Image Credit: Jeff Hicks)
advertisment
foreach ($line in $split) { [email protected]{Object=$line} switch -Regex ($line) { "Stopped" { $params.BackgroundColor = "Red"} "Running" { $params.BackgroundColor = "DarkGreen"} "Pending" { $params.BackgroundColor = "Magenta"} "Paused" { $params.BackgroundColor = "Yellow"} } Write-Host @params }
Highlighted lines (Image Credit: Jeff Hicks)
[regex]$rx = ([enum]::GetNames([System.ServiceProcess.ServiceControllerStatus])) -join "|"
I’ll process each line, but only do fancy coloring if the line contains a status keyword based on a regex match. If it does, I’ll write the first part of the substring up to where the match starts. I can find that from the Index number in the match object.
A regex match (Image Credit: Jeff Hicks)
advertisment
foreach ($line in $split) { $m = $rx.match($line) #only process if there is a match if ($m.success) { #get the point in the string where the match starts $i = $m.Index #display the line from start up to the match $line.Substring(0,$i) | write-host -NoNewline #select a foreground color based on matching status. Default should never be reached switch -Regex ($m.value) { "Stopped" { $fg = "Red" } "Running" { $fg = "Green" } "Pending" { $fg = "Magenta" } "Paused" { $fg = "Yellow" } Default { Write-Warning "Somehow there is an unexpected status" } } $line.substring($i) | Write-Host -ForegroundColor $fg } else { #just write the line as is if no match Write-Host $line } } #close foreach
And here’s the result:
Colorized status results (Image Credit: Jeff Hicks)
$keycolor = @{ Stopped = "Red" Running = "Green" StartPending = "Magenta" ContinuePending = "Cyan" StopPending = "Magenta" PausePending = "Cyan" Paused = "Yellow" }
These are the same values as the status enumeration. I still intend to use a regular expression so I will create one from the hashtable keys.
$keys = $keycolor.keys -join "|"
The principal is the same as the previous solution but the hashtable makes it a bit more dynamic.
foreach ($line in $split) { If ($line -match $keys) { [string]$m = $matches.Values[0].trim() #get index of match $i = $line.IndexOf($m) $line.Substring(0,$i) | Write-Host -NoNewline $line.Substring($i) | Write-Host -ForegroundColor $keyColor.item($m) } else { #just write line Write-Host $line } }
The end result is the same.
Different technique same results (Image Credit: Jeff Hicks)
More in PowerShell
Microsoft’s New PowerShell Crescendo Tool Facilitates Native Command-Line Wraps
Mar 21, 2022 | Rabia Noureen
Most popular on petri