Summary: Learn to split data in a Here-String and get a console beep.
Honorary Scripting Guy, Sean Kearney, is here with our final day this week to wrap up building a hexadecimal clock in PowerShell.
When we finished yesterday, we ran across a snag in our output. Most of our rows kept dropping to the immediate left of the screen as in the following image:
For this, we will look at one of our Here-Strings to try and figure out the problem:
$HexArray[8]=@'
888888
88 88
88 88
888888
88 88
88 88
888888
'@
If we look at a Here-String, you’ll notice it is literally a long string. It has an array count of 1 but a large length.
The question is, how can I access the individual rows? If we can identify the character at the end of a line, we could feed that to a split() method. This will turn this Here-String temporarily into an array.
We can run through a Here-String with this small loop in PowerShell to examine and view its values. The [byte][char] converts the letter or character to the ASCII number.
for ($x=0; $x -lt $HexArray[8].Length; $x++)
{
$Char=$HexArray[8][$x]
Write-Host $Char,([byte][char]$Char)
}
The output will look something like this, and please note the repeating patterns of 13 and 10 on the screen.
We can send error Character 13 (Carriage Return) or Character 10 (Linefeed) in to split this into an array. We’ll use the line, Linefeed, as our split character.
$CharacterArray=$HexArray[8].split([char][byte]10)
Now if we examine this, we have an array of data that we can step through.
$CharacterArray.Count
Now that the data is split into an array, we can step through this row-by-row and set the column each time. Here is our original loop that’s adjusted to split the Here-String and then output the data.
For ($Count=0; $Count -lt ($HexTime.Length); $Count++)
{
$Character=($HexArray[('0123456789abcdef/-' |`
Select-String -pattern ($HexTime[$Count])).Matches.Index])
$CharacterArray=$Character.split([char][byte]10)
# Loop through all members of the particular Here-String
For ($Row=0; $Row -lt $CharacterArray.count;$Row++)
{
# Position the Cursor
$Host.UI.Rawui.CursorPosition=$CurrentPosition
# Access the Value and print it
$CharacterArray[$Row]
# Move up the cursor to the next row
$CurrentPosition.Y=$CurrentPosition.Y+1
}
# Bump up the counter for the Column and reset the row
$CurrentPosition.X = $CurrentPosition.X+10
$CurrentPosition.Y = $StartPosition.Y
}
As it stands, we just drew a single row on the screen. To make this continue, we’ll need to wrap this whole operation in a do loop. One problem with this approach is that there will be a lot of flickering on the screen. What we really want is to update the clock each second that it changes.
For this, we’ll add in a simple trap for the time. We’ll remember the last time that it changed.
do
{
$HexTime=Get-HexTime
} Until ($Hextime -ne $LastHexTime)
Then, at the end of the loop, we’ll drop in a simple line like this:
$LastHexTime = $Hextime
One more fun thing. Wouldn’t it be cool to have a little “Tic” sound as each second passes by? (Well, I thought it would, or at least a neat way to irritate my coworkers )
We can do this with a simple beep on the console. I tweaked it down to a very short time and actually got a “Tic” sound.
[console]::beep(1000,5)
Wonder what it all looks like? You can download this script from the TechNet Script Repository.
That’s all there is to turning your PowerShell console into a hexadecimal clock! Thanks for sharing the time with us!
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