Draw Boxes and Lines in the Windows PowerShell Console Host
Summary: Microsoft MVP Sean Kearney shows how to draw boxes and lines in the Windows PowerShell panel while scripting three reusable functions.
Microsoft Scripting Guy Ed Wilson here. Just when I thought it was safe to open my e-mail, I get a tweet from Sean Kearney saying he has a present for me. Low and behold, Sean has sent me a really cool article.
Sean Kearney is a network administrator, a Microsoft Certified Technology Specialist in Windows Server Virtualization and Configuration, a Windows PowerShell MVP, and a Microsoft Certified Systems Engineer. Sean is a devoted and passionate computer enthusiast from the early 80s to the nowadays day, having used merely about every microcomputer ever. Sean taught himself estimator programming with 65xxmachine code, working with many technologies―but primarily Microsoft. Sean deals with "anything thrown at him," from gnawed keyboards to recovery of Exchange servers to networking setups and isolating the realm of the unknown. Currently, he tests and deploys merely almost any new Microsoft Engineering science; he also deals with users in an enterprise class surroundings. Sean loves Windows PowerShell, Windows 7, and Hyper-V, in that lodge. You will oftentimes find him hanging out online at http://www.powershell.ca.
Hither is Sean's article.
I decided to have some fun. Because isn't that why we got into computers in the commencement place? It was fun on some level? We enjoyed information technology? Right? So I was thinking back to my BBS days and ASCII fine art and plotting information on the console screen.
You run into, using the $HOST variable in Windows PowerShell allows you to move the cursor to any spot (within reason) on the console. After you take moved it, you can put something there. And then I'thousand thinking to myself, "Boy, I'd love to build a nice box on the screen!" And so I sabbatum downwardly and wrote a actually bad script. It was bad because information technology worked, but the coding was merely horrible and repetitive. What I ended up with (for a single box) was about four foreach loops, a whole pile of $host.ui.raw.cursorposition settings, and about 90 lines of lawmaking.
And then I started reexamine information technology. Because a lot of the code did really repeat in almost respects, I idea at that place had to be a better style. The outset part was easy. Make a function to position the cursor, mostly to brand the code more than readable, simply also because I happen to similar readable functions.
————— Set Panel Position —————-
function global:fix-ConsolePosition ([int] $ten ,[int] $y ) {
# Go current cursor position and store away
$position = $host .ui.rawui.cursorposition
# Shop new X and Y Co-ordinates away
$position .x = $x
$position .y = $y
# Place modified location back to $HOST
$host .ui.rawui.cursorposition = $position
}
————— Ready Console Position —————-
Next, I realized the code kept cartoon lines. So I idea, "Wouldn't information technology make more sense to take a smart function that could draw those lines"?"
So onto task number two. Make a function that doesn't just draw a line on the screen just would be smart enough to know whether I was doing it vertically or horizontally. Information technology would have to know how long the line was and ideally what coordinates to draw it on.
The function has to receive the X and Y position of where the line has to get, receive length, and know if it is a vertical line:
office global:describe-line([int] $x , [int] $y , [int] $length ,[int] $vertical ){
Then ready the line to start at the defined coordinates. My last part, fix-ConsolePosition, makes this very piece of cake:
set-ConsolePosition $10 $y
Now hither'due south where the fun starts. I could but draw a box with asterisks and be done, simply I'd similar it to look nicer. And so each line will start with an asterisk merely have a "-" or a "!", depending on whether it'due south drawn vertically or horizontally:
If ([boolean] $vertical )
{ $linechar = "!" ; $vert = 1 ; $horz = 0 }
else
{ $linechar = "-" ; $vert = 0 ; $horz = 1 }
Instead of a big funky { if so else }, I decided to necktie it into the math. So I sat down and thought out the flow of the lawmaking. Okay, all I did really was call up "If I'grand cartoon vertically, the Y coordinate will e'er alter; otherwise, 10 is always going to alter":
set-ConsolePosition (( $horz * $count )+$10) (( $vert * $count )+$y)
Then with this little line above here I make certain to keep the counter changing the value of the 10 position or the Y position (but not both) depending on how it receives the $Vertical from the function. This line
write-host $linechar -nonewline
will always be the same for cartoon because we have predefined the character we are drawing with. Overall, y'all get this to draw a line at present:
————— Describe line Function —————-
function global:depict-line([int] $x , [int] $y , [int] $length ,[int] $vertical ){
# Move to assigned X/Y position in Console
fix-ConsolePosition $x $y
# Draw the Get-go of the line
write-host "*" -nonewline
# Is this vertically fatigued ? Gear up management variables and advisable character to draw
If ([boolean] $vertical )
{ $linechar = "!" ; $vert = one ; $horz = 0 }
else
{ $linechar = "-" ; $vert = 0 ; $horz = one }
# Depict the length of the line, moving in the appropriate management
foreach ( $count in 1 ..( $length-1 )) {
set-ConsolePosition (( $horz * $count )+$x) (( $vert * $count )+$y)
write-host $linechar -nonewline
}
# Bump up the counter and draw the terminate
$count++
set-ConsolePosition (( $horz * $count )+$ten) (( $vert * $count )+$y)
write-host "*" -nonewline
}
————— Draw line Function —————-
Now here is where I went overboard. My brain went, "Hey, I can draw a line, I can option a management, I could make a box!" You tin can tell my brain didn't become a lot of holiday fourth dimension during the summer. But I gave in and idea it out. Really, a box wasn't so difficult. Two horizontal lines, two vertical lines. I already have a office to describe lines.
And then I could just telephone call upwards the line draw part with the advisable data and just run information technology right? Nope. I could but there was this geeky piffling voice proverb "Reuse the lawmaking!" So with a Foreach loop and some fancy math, I figured out a way to reuse almost every slice of sanity.
So I thought, what is unique about each line in a box? The position, the X/Y beginning position, and the length. So:
- The square would draw ii horizontal lines and and so two vertical lines.
- Each horizontal line the "X" position does not change for starting point.
- Each vertical line the "Y" position does not change for starting point.
Then you end up with a pattern like this:
- 0 Horizontal
- 0 Horizontal
- i Vertical
- ane Vertical
Each Row was either Top Left or Lesser Right:
- 0 Top
- i Bottom
- 0 Left
- 1 Right
Which gave me this pattern:
- 0 0 Top Horizontal
- 0 i Bottom Horizontal
- 1 0 Left Vertical
- 1 one Correct Vertical
We have a loop that goes through four times and can flip variables and do all sorts of funky stuff to make a box.
—————- Draw the Box ———————————-
function global:draw-box ([int] $width , [int] $length , [int] $x , [int] $y ) {
# Do the iv sides
foreach ( $box in 0 .. three ) {
# Variable to flip whether we're on the left / summit of the box or not
$side = $box%two
# Variable to switch whether information technology's a vertical or horizontal line
$vert = [int](( $box- . 5 )/ ii )
# compute the Width and Length so nosotros tin can "switch them"
$totalside = $width+$length
# Length of line volition exist dependant on the Direction
# (vertical or Horizontal)
$linelength = ( $vert * $length )+([int](! $vert )* $width )
$result = $totalside-$linelength
# flip in the correct Ten Y coordinates for the maximum
$ypass = ([int](! $vert )* $side * $event )+$y
$xpass = ( $vert * $side * $result )+$x
# Draw the line
draw-line $xpass $ypass $linelength $vert
}
}
—————- Draw the Box ———————————-
Then what exercise we have ? A series of iii functions, and a pretty box on the screen.
What have we learned?
- You tin use some incredibly powerful functions in Windows PowerShell.
- With proper math and functions, yous tin can make a lot of code reusable.
- Sean has way too much time on his hands.
Sean, thank you for sending me your post. I put all three functions into a single script, loaded it into my Windows PowerShell console, moved my console point, and drew a box and a line. The results are shown in the following image.
Nosotros would honey for you to follow us on Twitter and Facebook. If you have whatsoever questions, transport email to the states at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow when nosotros begin a new week on the Script Center. We volition have an awesome series of articles most Windows PowerShell cmdlets and SharePoint 2010, written by celebrated SharePoint author Niklas Goude. Until then, peace.
Ed Wilson and Craig Liebendorfer, Scripting Guys
thententonarmstead.blogspot.com
Source: https://devblogs.microsoft.com/scripting/draw-boxes-and-lines-in-the-windows-powershell-console-host/
Komentar
Posting Komentar