Back in early September, I wrote a post about “clearing” the host. I was proud of my simple, little function, that I then called clx, and so in early October, I linked the post on Twitter. To my surprise, a few well-known names in Windows PowerShell helped promote the blog post. I’m talking about PowerShell MVPs, authors, and community bloggers – the very people I look up to and learn from.
Just recently, I decided it would be wise to add comment-based help and some minor logic-based, error checking to the function, and then post it on the Microsoft TechNet Gallery. In addition, I wanted to combine it with another simple console function that I use, and upload them both as a module.
If you’ve read the link above then you already know about the first half of the module (the Clear-TMConsole function, aka clx). The second half of this module (the New-TMConsole function) simply opens a new PowerShell console and provides the user the option to keep, or close the current console. I wrote this function because there are many times when I want a fresh console that doesn’t have any left over variables. I was tired of typing Start-Process (or saps) powershell. I understand these are simple, but I’ve become quite dependent on them to speed up my work, and to mildly safeguard information I want to keep in my console(s).
Below are a few aliases I use to help speed up my use of the functions. Opening a new console, and closing the current one, is as simple as entering: nc y n and pressing enter. The y is to indicate to continue running the New-TMConsole function, and the n indicates to not keep the current console. Hopefully this module can be helpful to others, too.
I use the Clear-Host cmdlet alias, cls, throughout the day to clear out whatever typing I have inside my Windows PowerShell console. It does its job well, but recently I’ve wanted it to work differently. I wanted it to appear that the console host has been cleared, but still allow me to scroll back up to see what was on the screen before it was cleared. I started playing around with the console class, [Console]. While not necessary, this can also be written using the namespace, System, such as [System.Console]. I like the idea of being as complete as possible and so you’ll see me use the namespace even though it’s not necessary.
Before I could write something reusable, such as a function, I had to figure out if what I wanted to accomplish, was even possible. I knew I was working with [System.Console] and so I piped that to Get-Member, but it returned the methods and properties of System.RuntimeType, seen below.
I struggled for a moment until I remembered an article I had read on using static classes. I found that page again, http://technet.microsoft.com/en-us/library/dd347632.aspx, and was quickly reminded that using the -Static parameter of the Get-Member cmdlet would get me the correct results.
Running the command above produces the TypeName as shown, but it also produces all the methods and properties. I started looking over the properties and a couple about the cursor quickly caught my eye, especially the CursorTop property. After the Get-Member command from above, and based on the results of returning the CursorTop property, my cursor was positioned at line 59 inside my console, as can been seen in the example below on line 2. I cleared the screen, and beginning on line 4 below, I reran the command three more times. Each time, it gave me the location where the cursor was last positioned.
I decided I would assign the value, 0, to the CursorTop property and suddenly I was writing over the text on the top line. Take a close look at line 1 below.
I could move my cursor, great, but this wasn’t exactly what I wanted. What I wanted was to push that scroll bar down so that anything that was already on the screen was pushed off the top of my console, and all that was left was my PowerShell prompt. I still believed there was a way to do this and so I spent a little more time looking over the properties. I found four that began with Window – WindowHeight, WindowLeft, WindowTop, and WindowWidth – and began to experiment with them. I didn’t suspect I’d be doing anything with the height and width but I thought I would check out their values anyway – 50 and 120, respectively.
WindowLeft didn’t seem to be that important, because no matter how much was typed before I entered [System.Console]::WindowLeft, the property value was still set to 0. Then I entered in [System.Console]::WindowTop and it was also 0 every time. Then it dawned on me, what if I changed its value like I did with CursorTop. I tried it and my scroll bar started jumping all over. I’m getting close!
I thought I was done when I took another moment and scanned over the methods. I found one called SetWindowPosition. Instead of simply assigning a new value to the property WindowTop, I decided I would use the method to do the work for me. I eventually ran both of these options through the Measure-Command cmdlet and determined that there was no gain in speed by using one option over the other.
So, once I knew what to do, I opened my profile ($PROFILE) and created an empty function. For whatever reason, I called it clx thinking that this would be a good option for me. Turns out that while clx has little meaning, I was able to quickly remember it and start using it right away. Now, every time I want it to appear that I’ve cleared my host, but didn’t really, I type clx and press Enter.
Function clx {
[System.Console]::SetWindowPosition(0,[System.Console]::CursorTop)
}
I added one additional feature to this function as is seen in the example below. This option allowed me to run the clx function and leave the last n number of rows on the screen. Try it out by ensuring your have some output in your console and then entering clx 2. This will “clear” the console screen but still allow you to view the last two rows without scrolling back up. Try it and it may make more sense.
Function clx($SaveRows) {
If ($SaveRows) {
[System.Console]::SetWindowPosition(0,[System.Console]::CursorTop-($SaveRows+1))
} Else {
[System.Console]::SetWindowPosition(0,[System.Console]::CursorTop)
}
}
Here’s a video of the function in action. The first thing we do is return 5 processes and then 5 services. Then we use cls and notice that we cannot scroll back up to see what was cleared. This is the typical behavior. When we add the processes and services back, and then use the clx function, we can see that we have the option to scroll back up and see what was on the screen, before we “cleared” it.