DEV Community

Devin W. Leaman for 4lch4 Industires, LLC.

Posted on • Edited on

How To Uniquify Your PowerShell Console

Table of Contents

PowerShell Profile Basics

It's important to point out that knowledge of PowerShell profiles, while helpful ahead of time, isn't absolutely required to read this article and potentially gain some value. If you do wish to get some information ahead of time, I highly recommend taking a look at this blog post by The Scripting Guys' Ed Wilson.

There are only a couple things I think you need to know about profiles in PowerShell before continuing on:

  1. A profile is a script that allows you to customize your console by being executed as soon as you launch said console.
  2. There are 6 profiles you can utilize to choose exactly which console you'd like to customize.

What're We Trying to Achieve?

With that said, this is gonna be a long read so let's get started. Here is an image of my current console on startup (our end goal):

Custom_PowerShell_Console

I like it to show me the current weather report, and I've customized the prompt line to show the current directory name and time as opposed to the standard look:

Default_PowerShell_Console

To-Do

So, this means we have 3 "tasks" to complete for our desired look:

  1. Add the weather API for our date integration
  2. Add the current time to the beginning of the current shell line
  3. Add the current directory to the end of the current shell line

Where Do We Start?

To be completely honest, as I started to write this post I realized I had no idea how I did this aside from having to overwrite a function in my profile called global:prompt I believe. So, I opened my profile script in PowerShell Studio which is located at C:\Users\Alcha\Documents\WindowsPowerShell\Profile.ps1 and saved a backup copy (Profile_Backup.ps1). Then, a lovely Ctrl + A → Backspace so we have a clean slate.

First up, we need to find out how to customize the prompt itself, so a quick google search will get us started. The first three results were more than enough to get me what I needed. Personally, I prefer reading examples over documentation so after scanning over the three links, I chose to focus on the third as it seemed rather lengthy and full of examples. After reading a bit more, I realized it was more focused on posh-git specifically, so I switched back to the Scripting Guys response written by Sean Kearney.

Customizing the Title/Prompt

While Sean first covers how to customize the title of the window, this is something I didn't know about before and wound up changing in my profile, so hooray for new stuff! More specifically, I started by adding this line to customize the $Host.UI.RawUI.WindowTitle property:

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

While it was neat, I didn't quite like the format:

Customized_WindowTitle-1

After some tinkering, I landed on the '%y/%m/%d %R' format. Which you'd use like Get-Date -UFormat '%y/%m/%d %R' , and your result should look something like this:

Customized_WindowTitle-2

Now that I've got my title the way I want it, on to the rest. Next, Sean mentions the default prompt function, which is what's executed every time your prompt is displayed:

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

Bingo! Now we can take care of the 3rd item on our To-Do list: Add the current directory to the end of the current shell line To do this, we need to get the current working directory, which is available a number of ways. We can either use the $PWD variable which stores the current variable, or we can use the Get-Location cmdlet, which is what we'll be doing.

Get-Location by default returns the entire current path, but we're only interested in the last portion of it, so we can get that part by using the Split-Path cmdlet:

Split-Path (Get-Location) -Leaf # Gives us 'Alcha'

Now we need to combine knowledge of the Prompt function, how to get the current date/time, and the Get-Location cmdlet to get our desired result. The function will end up looking something like this:

function Prompt {
  $Host.UI.RawUI.WindowTitle = (Get-Date -UFormat '%y/%m/%d %R').Tostring()

  Write-Host '[' -NoNewline
  Write-Host (Get-Date -UFormat '%T') -ForegroundColor Green -NoNewline
  Write-Host ']:' -NoNewline
  Write-Host (Split-Path (Get-Location) -Leaf) -NoNewline
  return "$ "
}

We need the -NoNewLine parameter in order to put all of the text on the same line. This also allows us to separate it all into 5 separate lines and color the current time green while the rest remains the default white. Lastly, I moved the line to customize the title here because now whenever the prompt is updated, so is the title, and it'll show the "current" time. Now our console should look like so on startup:

Customized_Prompt-1

With that, we've got two items from our To-Do list complete, and we can move on to the easiest part, which is adding a weather API to display the current conditions for our area.

Getting The Weather

Now, to get the weather we'll be using the OpenWeatherMap service, mostly because I found a script at some point in the past that automatically formats the output into what you saw in the first screenshot. In order to use the service though, we need to get an API key that we can pass to the script.

When you create an account on OpenWeatherMap, go to the API keys portion of your account, which if you can't find is available here. Create a key and name it whatever you want, I just left mine as "Default":

Open_Weather_Map_API_Key

Now that we have a key, we need to add the Get-Weather script to our profile. The way I did this was I created a new script in my profiles directory (C:\Users\Alcha\Documents\WindowsPowerShell\) called Get-Weather.ps1 and then copy/pasted the content of the script from GitHub. I'm bit of a stickler for variable naming conventions and capitalization so after some refactoring, I wound up with a script that looks something like this:

Get-Weather_Script-1

I won't cover the meat and bones of the script, as this is already a rather lengthy post 😅 but the full text of "my" version of obs0lete's script is available as a gist, you just need to plug in your API key for it to function properly. Now to use this, we need only dot-source the file in our profile and then call the Get-Weather function to kick it all off:

Weather_Added_To_Profile

You'll of course have to change the API key, city, and country to values that work for you, but it's fairly simple. Something to note, I found a hard time with the actual city I live in, as there's a number of other cities in the USA with the same name. This meant I was getting really weird weather results from the API, imagine it saying it's raining outside when it's bright and sunny. I fixed this by finding the neighboring large city and using their name instead:

Custom_PowerShell_Console-2

Conclusion

It's important to note that I changed the original Get-Weather script just enough to make it work for me, so be sure to make any adjustments you might need. For example, I mentioned adjusting the variable names, but I also updated the units from Metric to Imperial and made it so it would output the Attempting URL... line mostly for debugging but also as a test for if the API isn't working for whatever reason.

I hope this wasn't too painful of a read, I did my best to only cover the interesting bits of solving this problem and leave out any fat that was just dull or involved me spacing out and endlessly scrolling 😂 If you have any questions, comments, or concerns, please feel free to reach out to me on any of my social networks or email me at admin@alcha.org.

Top comments (9)

Collapse
 
myleftshoe profile image
myleftshoe • Edited

Helped me too

Powershell
Powershell

vs.

Zsh
Zsh

Collapse
 
4lch4 profile image
Devin W. Leaman

Whoa.. Can you provide the code to make posh look like that?

Collapse
 
myleftshoe profile image
myleftshoe • Edited

Here you go: [Link to code on GitHub]

Plus a couple of other examples. I got a bit obsessed with this - you could say I've developed a terminal illness.

Example 1

The colored panels above only appear when the state changes, e.g. cd to another directory or git status changes. Otherwise it shows a minimal prompt. Current time and duration of last command are also displayed

Example 2

First one with more info in panels
Example 3

Collapse
 
lwndwsk1 profile image
Frank Lewandowski

Here is mine.. with autosuggestion e.g. History
Powershell1

And here with "lsd" instead "ls" command.. i like it a little more minimal ;-)
Powershell2

Collapse
 
moinulmoin profile image
Moinul Moin

how did you do this? give me the resource please

Collapse
 
iglesk profile image
Omar AlSabek

Thank you so much !! I love It!

Collapse
 
4lch4 profile image
Devin W. Leaman

No problem! Happy to help 😊

Collapse
 
shostarsson profile image
Rémi Lavedrine

Very interesting. I didn't know that you could customize Powershell like that.
I would love to see something like the Spaceship prompt for Powershell.

Collapse
 
4lch4 profile image
Devin W. Leaman

Huh, I've never heard of that before but I'm immediately interested. I'll see if this can't be done for PowerShell.