Weekend Scripter: Customize PowerShell Title and Prompt

Summary: Learn how to interactively update the Windows PowerShell prompt and title.

Honorary Scripting Guy, Sean Kearney, is here today to have a little bit of fun with the Windows PowerShell console. Why not? It’s a Sunday, it’s the last day of my time off, and I feel like playing.

There have been many posts online about the fun you can have with the $Host.UI.RawUI object in Windows PowerShell. You can use it to edit cursor locations, flip colors about…almost anything your little heart desires.

Another fun little thing we’re going to play with is the Windows PowerShell prompt. Yes! You’re allowed to mess around with this. It’s completely OK because we’re going to make this change through our personal PowerShell profile.

This means if we decide we don’t like what we did, we can remove it from the $Profile file and everything will revert to the default.

For the first fun piece, were going to change the title on the PowerShell bar. It’s actually very easy to read and write to the $Host.UI.RawUI object. If you’d like to see the current title, simply access the WindowTitle property:

$Host.UI.RawUI.WindowTitle

If you’d like to have some fun, with one line, you can add the Time and Date to the current title:

$Host.UI.RawUI.WindowTitle=(Get-Date).tostring()

Sure, neat trick. But this only updates once, which is neat, but not really useful.

I suppose I could find some funky cool way to play with events and triggering, but how about a simpler approach? How about each time I hit ENTER in the console, the Date and Time are updated? It wouldn’t be quite “real time,” but it would work. This is where we get to play with the PowerShell prompt.

The prompt is actually a very simple PowerShell function. The neat thing is that you can edit this function. To pull up the properties of this function, access the ScriptBlock parameter:

(Get-Command Prompt).scriptblock

Here is the default code for the prompt in Windows PowerShell. If you look at it, it’s a just simple script that displays a line of text:

"PS $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) "
# .Link
# http://go.microsoft.com/fwlink/?LinkID=225750
# .ExternalHelp System.Management.Automation.dll-help.xml

Hmmm…An ongoing script, eh? I could have a lot of fun with this!

I could even have the prompt beep every time I hit ENTER. I just need to redefine the function. To ensure that I maintain anything Microsoft wanted to be in there, I use the original code as a base at all times. Here we’ve added a single line to make it beep—just to be irritating:

Function Prompt
{
"PS $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) "
[console]::beep(2000,500)
# .Link# http://go.microsoft.com/fwlink/?LinkID=225750
# .ExternalHelp System.Management.Automation.dll-help.xml
}

Isn’t that kinda neat? Because this simply a function (albeit a very special function, which is called every time we hit ENTER in the console), we could use this to update our title bar. But we could do so much more. This is the line that displays the current folder and path:

"PS $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) "

I can actually capture this data and use it in my title bar. The reason you might want to do this? Sometimes the path can get pretty deep, and it eats up half the desktop real estate in the console. But the information is relevant, so I don’t want to lose it.

First I’ll capture the current prompt data:

$PromptData="PS $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) "

Now I’ll update the title bar with the information from the prompt and the current date and time. I add a little hyphen to make it more readable:

$Host.UI.RawUI=$PromptData+’-‘+(Get-Date).tostring()

If I don’t do anything more, Windows PowerShell will default to a prompt of PS.

Now all I need to do is add this block of code to my PowerShell profile. Here’s the updated function:

Function Prompt
{
$PromptData="PS $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) "
$host.ui.RawUI.WindowTitle=$PromptData+’-‘+(Get-Date).tostring()
# .Link# http://go.microsoft.com/fwlink/?LinkID=225750
# .ExternalHelp System.Management.Automation.dll-help.xml
}

When I run this in my current PowerShell console, I get cool results like this!

Image of title bar

This is a fun example, but can you imagine the fun things you could do with the prompt and the title now? Let your imagination be your guide!

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