Use Bold font in Write-Host
It is not a great discovery but probably useful to some of you PowerShell scriptwriters out there.
Currently I am on a holiday in Croatia and where most people find it relaxing to spent 3 weeks looking at other people in the swimming pool, I enjoy to improve my coding skills and do the things that I usually don’t have the time for. Although I am sitting at the swimming pool with 34 C and a laptop on my sun bed.
This week I started developing a PowerShell module for a new feature in Microsoft Sentinel. As with every script or module that you create, one of the important things to write is proper error handling. In some cases an expected error can occur, so I was looking for a method to show a custom error message other than just using Write-Error
.
This because I don’t always want to show an ugly message containing the line number etc. but just a friendly message.
I noticed that if an error occurs in a built-in module, the errors are always shown in bold where my messages just showed in normal font with just the selected color using -ForegroundColor
property.
To keeping the experience as close as possible to the default Microsoft modules behavior, I was wondering if it was possible to output my messages in the same bold font type.
The Markdown language
Markdown is a markup language that describes what plain-text should look like, and can be used to create formatted text using a plain-text editor. As the Write-Host module only supports plain-text it is worth the shot to see what happens if we add the markdown notation to our message body.
$message = "**Write this as bold**"
Write-Host -Message $message -ForegroundColor Red
I was already expecting that this wouldn’t work, but it is always worth trying. So in my first attempt to get my bold written text I added the markdown notation to my Write-Host
command by adding **<string>**
to the message.
I completely makes sense that this isn’t working because the asterisks is nothing more than a representation of the ASCII CODE 42 value (okay, we are getting geeky here)
Markdown PowerShell Module
Another little hidden gem is the built-in module ConvertFrom-Markdown
in PowerShell. This module can be used to convert the file content or strings to Markdown. Now that might be something useful in the solution to our objective.
There is also a
ConvertTo-Markdown
module available, but this is a community project and not available by default in PowerShell.
Based on the documentation it is possible to describe out formatting in plain-text and convert this notation to a markdown output. Let’s see if we can achieve this.
In the following example we are using the same message as in the previous attempt to format our text. The cmdLet outputs a System.Object
of the type Microsoft.PowerShell.MarkdownRender.MarkdownInfo
and responds by default with a HTML value. By adding the -AsVT100EncodedString
switch, the result will be processed as Markdown.
$message = "**Write this as bold**"
ConvertFrom-Markdown -InputObject $message -AsVT100EncodedString
Putting it all together
Now this starts to look very promising, and seems to go in too the right direction. Our next step will show how we can combine this with the Write-Host
Cmdlet.
In the preview steps we have learned 2 things.
- Write-Host does not support a markup language notation for formatting.
- ConvertFrom-Markdown returns an object with the formatted text.
We need to select the correct value from the result object that comes out of the ConvertFrom-Markdown
CmdLet, So we need to do some small adjustments to the object that we are feeding to the Write-Host
Cmdlet.
By putting the input value for the Write-Host
write-host between parenthesis, this conversion of the plaintext to Markdown will be processed first. By adding .VT100EncodedString
after the parenthesis the correct value from the output object is selected.
$message = "**Write this as bold**"
Write-Host ($message | ConvertFrom-Markdown -AsVT100EncodedString).VT100EncodedString
BANG, that actually works!
Below you can see a couple of examples of the normal output and the output that comes out of our Markdown method.
Things to consider
There are a couple of caveats that needs to be taken into account.
The ConvertFrom-Markdown
module adds an empty line `n
to the output.
If you want to get rid of this, you need to add a string replace command to the output.
Write-Host (("**Hello World**" | ConvertFrom-Markdown -AsVT100EncodedString).VT100EncodedString).Replace("`n", '') -foregroundColor Cyan -NoNewline
When only formatting one word as bold and combine this with the -ForegroundColor
switch, only the text until the Markdown is processed.
$message = "Hello **World**, this whole line should be in the same color"
Write-Host ($message | ConvertFrom-Markdown -AsVT100EncodedString).VT100EncodedString -ForegroundColor Yellow
I still believe that it is always best to use the build-in CmdLets for showing error and verbose messages. But in some cases it can be useful to create a more customized output.
But for the times that they don’t exactly do what you wished for, this can be a solution.
Happy Coding!