Build a hexadecimal clock in PowerShell – Part 4


Summary: Use PowerShell to navigate the neutral zone.

Honorary Scripting Guy, Sean Kearney, is here today to continue forth (not COBOL nor even Visual BASIC) into our silly yet fun quest to build a hexadecimal clock by using the PowerShell console.

It does seem silly, doesn’t it? Yet, consider some of the things that we’ve learned in PowerShell during our quest.

  • Here-String
  • Defining array
  • Select-String searches
  • Convert number bases
  • Singing songs about huge tracts of land… (Oh no, wait…. Sorry… That was a movie I watched last night.)

So, although the quest seems silly, we have learned quite a bit.

Actually, it's much like any quest. The goal isn’t the point. It’s what you learn or experience while getting there.

Our next part is to figure out how to draw this silly thing. Oh, well, good grief!

I hadn’t really thought this one out.

So far, we have a string of characters (Our HexTime).

From this string, we need to identify the members of our array and show them (Giant Letters from Mars).

That part seems simple enough. We can just loop through and show the output.

For ($Count=0; $Count -lt ($HexTime.Length); $Count++)

{

$Character=($HexArray[('0123456789abcdef/-' | Select-String -pattern ($HexTime[$Count])).Matches.Index])

$Character

}

This is a variant on yesterday’s exercise, but it goes one step further. Access the array from the Index value and show the relevant character. This actually works if you want a vertical clock.

I really want a horizontal clock, like the one on my desk. To achieve this in the console, I need to figure a way to move the cursor to a unique position on the screen.

We can use the $host variable, which is a live object in the PowerShell console that contains information such as the color of the screen and cursor position.

With this object, we can see, capture, and, most importantly, set the position of the cursor in the console.

Neat, eh? Let’s clear the screen and capture the current location.

Clear-Host
$Position=$host.ui.RawUI.CursorPosition

If you look at the current object, you’ll see the following results:

Screenshot of the cursor position.

This tells us that the cursor is at column 0 and row 0 (the very top) after we just wiped the screen.

Now, to modify where the cursor is going to be, we do three things.

  • Capture the position
  • Set the X and/or Y values in the captured object
  • Set the position from the captured object

An example of this in action by using Windows PowerShell (followed by Write-Host of some output) can be seen in the following example:

$CursorPosition=$Host.UI.Rawui.CursorPosition
# Set column to 20
$CursorPosition.X=20
# Set row to 15
$CursorPosition.Y=15
# Set Cursor Position
$Host.UI.RawUI.CursorPosition=$CursorPosition

If we’d like to have each of these characters at a unique position, we’ll need to pick a start point and then adjust the column. My Here-Strings are at least eight characters wide, so I’d like to adjust the column by 10 each time. Here’s a basic loop that will:

  • Set the start position
  • Adjust the column by 10 each time
  • Place a character from the array on the screen

# Clear the Screen
Clear-Host
$StartPosition=$host.ui.RawUI.CursorPosition

# Set the Home Position for the clock
$StartPosition.Y=3
$StartPosition.X=4

# Remember where we started
$CurrentPosition=$StartPosition
For ($Count=0; $Count -lt ($HexTime.Length); $Count++)
{

# Set the cursor location
$Host.Ui.RawUI.CursorPosition=$CurrentPosition

$Character=($HexArray[('0123456789abcdef/-' |`
Select-String -pattern ($HexTime[$Count])).Matches.Index])
$Character

# Bump up the counter for the Column and reset the row
$CurrentPosition.X = $CurrentPosition.X+10
$CurrentPosition.Y = $StartPosition.Y
}

But when we run through the loop, we get this result:

Screenshot of results from running through the loop.

My first row of each character is placed correctly, but the rest seem to end up on the same spot. Why is that?

The trick is that with each Here-String is a character that forces the cursor back to column 0 for the additional rows.

If only there was a way to place each row of the Here-String and set the cursor position. We’ll go into that way tomorrow, of course!

I invite you to follow the Scripting Guys on Twitter and Facebook. If you have any questions, send email to them at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow.

Until then always remember that with Great PowerShell comes Great Responsibility.

Sean Kearney
Honorary Scripting Guy
Cloud and Datacenter Management MVP

Comments (0)

Skip to main content