Tag Archives: Linux

Linux Prompt X


Notice: The following post was originally published on another website. As the post is no longer accessible, it is being republished here on tommymaynard.com. The post was originally published on March 30, 2019.


Note: Because this is republished post, I know there is an update coming on this topic. Be sure to watch for this on Wednesday, February 17, 2021. I will do my best to remember to link to it once it is available.

“This is the one.” -Me (about ten seconds before starting this article)

For a decent amount of time now, I’ve used a personalized prompt. On several occasions even, I’ve written and shared it with the PowerShell community. Well, I’m about to do the same thing today. That said, I’ve never quite felt what I’m feeling now. After all those iterations, I feel that this version — version X (ten) — is what I was always after. It makes sense on Windows and Linux, and it provides everything I could want in a prompt.

For full disclosure, I’ve actually… said that last sentence before.

Let me explain a bit about it for those that may be new. I’ve always appreciated the Unix/Linux prompt, as it includes with it, the user name, the host/computer name, and often, an indication of whether or not I’m running as root ($ vs. # [# is root/admin]). Over time, I brought this and more into my prompt on Windows. It was the Linux prompt on Windows. And now, it’s even the Linux prompt on Linux, too. You know, that whole PowerShell Core, cross-platform thing. No kidding, but I was actually kind of surprised when I installed PowerShell Core for the first time and it used the same, standard PowerShell prompt. I suppose it’s something we’ve come to expect, however.

Before we discuss how to get the code, let’s discuss what I’ve done. I’ve now included everything, inside of a single advanced function called Switch-Prompt. If you run it with just the command name, you’ll get the standard, PowerShell prompt. That’s because the default value for the Type parameter is “Standard.” It can also be run using that parameter and parameter value, as seen in the below example.

PS > Switch-Prompt -Type Standard
PS C:\Program Files\7-Zip\Lang>

When using the Type parameter value of “Standard,” the prompt will look and function just as it typically does in PowerShell. Until Switch-Prompt is invoked again, this will be the prompt each time a new prompt is created (Enter is pressed).

The fun begins when we change out the “Standard” parameter value to “Linux.” This prompt will … well, let me just show you.

PS > Switch-Prompt -Type Linux
[tommymaynard@tmlaptop Lang]$ Switch-Prompt
PS C:\Program Files\7-Zip\Lang>

This option will create the prompt as open square bracket, current user name, @ symbol, current computer name, current directory, close square bracket, and either a dollar sign ($) or hash symbol (#). Remember, the hash symbol indicates that the user is running as root, or admin and the dollar sign indicates that the user is running as a normal user.

Using “Linux” as the value for the Type parameter creates two dynamic parameters. The FullPath parameter will include the full path to the current directory, and the Version parameter will include the version of PowerShell between the closing square bracket and the dollar sign or hash symbol. These two parameters can be used one at a time, or together — it makes no difference. In the below examples, I’ve pressed Enter a couple of times between commands, so you can see that the new prompt stays around until Switch-Prompt is invoked again, in a different manner than it was previously.

PS C:\Program Files\7-Zip\Lang> Switch-Prompt -Type Linux
[tommymaynard@tmlaptop Lang]$
[tommymaynard@tmlaptop Lang]$
[tommymaynard@tmlaptop Lang]$ Switch-Prompt -Type Linux -FullPath
[tommymaynard@tmlaptop c/Program Files/7-Zip/Lang]$
[tommymaynard@tmlaptop c/Program Files/7-Zip/Lang]$
[tommymaynard@tmlaptop c/Program Files/7-Zip/Lang]$ Switch-Prompt -Type Linux -Version
[tommymaynard@tmlaptop Lang]5.1.1$
[tommymaynard@tmlaptop Lang]5.1.1$
[tommymaynard@tmlaptop Lang]5.1.1$ Switch-Prompt -Type Linux -FullPath -Version
[tommymaynard@tmlaptop c/Program Files/7-Zip/Lang]5.1.1$
[tommymaynard@tmlaptop c/Program Files/7-Zip/Lang]5.1.1$

At an earlier time in this prompt’s development, I opted to have it allow me to choose the username and computer name. That’s still with us. When we use “LinuxCustom” as the value for the Type parameter, we get even more dynamic parameters. We still have FullPath and Version, but now, we also have UserName and ComputerName. Unlike FullPath and Version, these are not switch parameters; they require a value to be included along with them. Take a look at these final examples, and then you can get the code for yourself!

[tommymaynard@tmlaptop c/Program Files/7-Zip/Lang]5.1.1$ Switch-Prompt -Type LinuxCustom
[fake_user@fake_computer Lang]$
[fake_user@fake_computer Lang]$
[fake_user@fake_computer Lang]$ Switch-Prompt -Type LinuxCustom -UserName tm
[tm@fake_computer Lang]$
[tm@fake_computer Lang]$
[tm@fake_computer Lang]$ Switch-Prompt -Type LinuxCustom -UserName tm -ComputerName srvx
[tm@srvx Lang]$
[tm@srvx Lang]$
[tm@srvx Lang]$ Switch-Prompt -Type LinuxCustom -UserName tm -ComputerName srvx -FullPath -Version
[tm@srvx c/Program Files/7-Zip/Lang]5.1.1$

Now, it’s time for you to try it out yourself. In the past, I opted to save it in a public Gist, but this time, I think it’s good enough to go straight to the PowerShell Gallery. Here’s the Switch-Prompt’s page on the gallery, and here’s the command to issue in PowerShell to install it on your computer, as the current user. Remember, it’s a script, not a module. Therefore, you need to dot-source it, to use it, which is something that could be easily added to your profile script. That command is below, as well.

PS > Install-Script -Name Switch-Prompt -Scope CurrentUser
PS > . "$HOME\Documents\WindowsPowerShell\Scripts\Switch-Prompt.ps1"

Be sure to swap out “WindowsPowerShell” for “PowerShell” in the above path, if you installed it using PowerShell Core. It works there too! Even in the recently released 6.2 version.

Linux Prompt on Windows – Part IX

In the last installment of this series, just published a day ago, I mentioned that I’d like to be able to pass in the fake username and computer name to my prompt function, instead of relying on a hard coded value. Let’s back up, but seriously, only for a second. There’s only so much I’m willing to repeat if you’re starting to read this series at the ninth installment. You can use the links at the very bottom to easily access any of the previous posts.

My prompt function includes my real username and computer name. At times, I like to switch it to a fake username and computer name, so that screen captures won’t include my real information. These hard coded, fake username and computer name values are inside my prompt function as “tommymaynard@cpux1789.” Until now, I wasn’t able to choose the fake username and computer name, and that’s why we’re here today. I’ve added a way to make these values dynamic. I’ve included everything you’d need to copy to your $PROFILE script in order to use this same prompt function. I warn you however, once you start using it, you may not want switch back. And that’s fine, because it just got better.

Here’s an example, before I include the current prompt code. Do notice that the new UserName and ComputerName parameters are completely ignored when the Type parameter value is “Real.” This is because they are not needed in order to use the real username and computer name.

Unfortunately, the Set-Prompt function didn’t feel like a job for ParameterSets. I imagine I could have accomplished “adding” the UserName and ComputerName parameters, when the Type parameter had a value of “Fake,” using dynamic parameters; however, that’s just way too much involvement for now, and would likely bring little return on the invested time. I can be happy with this, at the moment.

Here’s the newest version. Copy it to your $PROFILE script and try it out! You will need a fake, default username and computer name. Toward the bottom of the code, inside the parameter section of the Set-Prompt function, swap out “tommymaynard” for your default, fake username, and “cpux1789,” with your default, fake computer name.

https://gist.github.com/tommymaynard/0dc88b5927ab5f63ee4738d87252fd63

Part VIII | Part VII | Part VI | Part V | Part IV | Part III | Part II | Part I

Linux Prompt on Windows – Part VIII

Update: There’s a part nine, now.

This, is the topic that will never die.

I’m literally about to begin the eighth installment on this topic. There’s no question about it, I love my prompt. In the last installment, we added a more complete PowerShell version number to the prompt, and the entire version number to the WindowTitle. We also added a Type parameter to the prompt function. This allowed me to manually (yuck) edit my function’s Type parameter default value between “Real” and “Fake.” Well, those days are done.

As of now, I’ve removed the default assignment of the Type parameter ([string]$Type = ‘Real’) in the below prompt function. Instead, I added a second function. It’s toward the bottom of the included code, so let’s meet down there.

https://gist.github.com/tommymaynard/4a544e89f71c00abf3611eb18971c71e

Hello again.

The additional function is called Set-Prompt. As the prompt function and this function are in my $PROFILE script, I can expect that they’re both loaded into memory each time a PowerShell host program is opened. In addition to loading the Set-Prompt function into memory, my $PROFILE script also invokes the function. Even though Set-Prompt has a default value for the Type parameter (much like the prompt function had previously), I still pass the “Real” parameter value to the Type parameter.

What this provides is an assurance that my prompt will always be real (include my real username and computer name), when I open a new PowerShell host. If I want to change it to my fake username and computer name for a screen recording, or screen captures, I simply run the below command. The Set-Prompt function doesn’t truly interact with the prompt function. What it does instead, is it updates the $PSDefaultParameterValues variable, so that every time the prompt function is invoked (each new prompt is created), it includes the correct Type parameter value even though we don’t actually see it entered.

Set-Prompt -Type Fake

Since I can’t seem to get away from adding more to my prompt function and this topic, perhaps we’ll do a ninth installment. I would kind of like a way to pass in the fake username and computer name, too. As of now, those values are still hard coded in the prompt function.

Update: I decided to add a graphic to this post. In the below image, although it looks like two different consoles, we’re actually working in the same PowerShell console. In each instance where it was necessary I hid a portion of the computer name. This may actually assist in seeing the real vs. the fake prompt, as I hid a part of my real computer name. The red line helps to indicate the same command in each image.

Part VII | Part VI | Part V | Part IV | Part III | Part II | Part I

Linux Prompt on Windows – Part VII

Notes: There have been updates to this post since it was first published. See those notes near the bottom of the post.

There no huge changes between the most current version of my Linux prompt and this one, but it has changed. Because of that, I’ve decided a new post is in order. All the other related posts are linked below.

I took a brief look, and here’s what’s changed between this version and the last.

– There’s a $CustomPrompt variable. You can manually set this to either “real” or “fake.” If it’s “real,” it’ll use the true user and computer name in the prompt. If it’s “fake,” it will allow you to use your own fake user and computer name. In this case, it’ll use whatever has been assigned to the $UserComputer variable. Enter the fake user and computer name as <username>@<computername>. As you can see in the code, it currently says tommymaynard@cpux1789. I tend to use this for demos and screen captures where I don’t want my true username and computer name included.

– The other update here was a modification to the version number. Previously we’d have 2.0, 5.1, and 6.0 at the end of our prompt, and in the WindowTitle. Since the release of 6.0.2, the prompt now includes the first digit of the build, or patch number (it was changed to patch in 6.0). The WindowTitle, however, will include the full patch, or build number. Take a look at this screen capture.

I get the feeling someone might see all this code and think the prompt will load too slowly. It doesn’t. But as proof, I’ve included a quick Gif of the prompt in action. Maybe it’s slower than it should be, but even if it is, I bet you can’t tell. Each time a new prompt appears (Enter key is pressed), the below prompt function code has executed. Yeah, it’s not slow, so no worries on the prompt function length (60ish lines).

And without wasting any more of your time, here’s the prompt code. Drop it into your $PROFILE .ps1 file and give it a run. Like me, you just might find out you want it everywhere.

https://gist.github.com/tommymaynard/7f5907c9a4952a7f77b02c85801d3653

Update I: After posting my prompt function, I noticed something that didn’t make sense any longer. The variable assignment of $UserComputer was outside of the real/fake If-ElseIf statement. Therefore, that assignment was moved into the If portion, as it only needs to be set if the prompt is going to use the the real username and computer name.

Update II: I grew tired of the mid function $CustomPrompt variable assignment, and instead opted for a Type parameter that took care of this assignment. While you can’t pass the parameter value at run time, it’s better than burying the variable assignment deep in the prompt. Due to this, there were a few changes that had to be made to the If and ElseIf conditions. This was nothing more that changing $CustomPrompt to $Type (the newly added parameter).

Update III: Yes, another update (to the above code). Previously the switch statement that determined the host for the WindowTitle didn’t have a default value. That’s to say that if you were using a host other than the ConsoleHost, the Windows PowerShell ISE Host, or the Visual Studio Code Host, it would enter nothing in the WindowTitle before the PowerShell version number. Now, it’ll enter $Host.Name… whatever that ends up being.

Update IV: I removed my code and embedded the GitHub Gist where I’ve been keeping my prompt (outside of my $PROFILE script, of course).

Part VI | Part V | Part IV | Part III | Part II | Part I

Linux Prompt on Windows – Part VI

My most recent post in the Linux Prompt on Windows series, is Part V. Now, we’re on VI and it’s all because of PowerShell 6.0.

As 6.0 uses a different $PROFILE script, it was mandatory that I created a new one and quickly copied over my Linux prompt. I hate to be anywhere without it. You can create a $PROFILE script in PowerShell 6.0 the same way we did previously. It’s New-Item -Path $PROFILE -Force (press Enter) followed by notepad $PROFILE (press Enter) to open the file, in Notepad, which should be obvious.

The newest change is adding the version number, just to the right of the host program’s name in the WindowTitle. Here’s an example of how that appears. As it should the WindowTitle indicates it’s PowerShell 6.0.

Type in powershell.exe and press Enter, and the WindowTitle changes. Now we’re in PowerShell 5.1.

Go deeper in time and type powershell.exe -version 2, press Enter, and it changes again, but this time to 2.0. By adding this addition to the WindowTitle via my prompt function, I can move between versions of PowerShell, if needed, and always know the version in which I’m working.

I’ve included the fully updated prompt function below. Copy it into your $PROFILE script, restart PowerShell, and enjoy. I can’t be the only one to appreciate this prompt, especially as PowerShell 6.0 just went GA. As the beta versions before it were, it’s cross platform; therefore, my lookalike Linux prompt makes even more sense now.

Update: I recently cleaned out my new 6.0 $PROFILE script and did what I’ve always done instead. That is to dot source a different profile script (the one loaded by Windows PowerShell 5.1). So, in place of my prompt function, I now have this entry: . C:\Users\tommymaynard\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1. Yeah, you’re reading that right, “WindowsPowerShell.” All my stuff is in there! It should be fun to see what works and what doesn’t!

Update: I got really tired of looking up at the WindowTitle to see my version, so I added it to the prompt, as well. It’s just after the closing square bracket and before the # or $ symbol. By the way, the difference of those two is that # indicates an administrative user, and $ indicates a non-administrative user. Oh yes, and for today, my host is blue. It’s not the exact blue, but close. The font color is also gray (by default), another slight difference between the host configuration for 5.1 vs. 6.0. Anyway, I’ve updated the below code to indicate the version as a part of the prompt itself, just like in the below image.

Function Prompt {
	(Get-PSProvider -PSProvider FileSystem).Home = $env:USERPROFILE

	# Determine if Admin and set Symbol variable.
	If ([bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).Groups -match 'S-1-5-32-544')) {
		$Symbol = '#'
	} Else {
		$Symbol = '$'
	}
	 
	# Write Path to Location Variable as /.../...
	If ($PWD.Path -eq $env:USERPROFILE) {
		$Location = '/~'
	} ElseIf ($PWD.Path -like "*$env:USERPROFILE*") {
		$Location = "/$($PWD.Path -replace ($env:USERPROFILE -replace '\\','\\'),'~' -replace '\\','/')"
	} Else {
		$Location = "$(($PWD.Path -replace '\\','/' -split ':')[-1])"
	}

	# Determine Host for WindowTitle.
	Switch ($Host.Name) {
		'ConsoleHost' {$HostName = 'consolehost'; break}
		'Windows PowerShell ISE Host' {$HostName = 'ise'; break}
        'Visual Studio Code Host' {$HostName = 'vscode'; break}
		default {}
	}

    # Determine PowerShell version.
    $PSVer = "$($PSVersionTable.PSVersion.Major).$($PSVersionTable.PSVersion.Minor)"

	# Create and write Prompt; Write WindowTitle.
    $UserComputer = "$($env:USERNAME.ToLower())@$($env:COMPUTERNAME.ToLower())" 
    $Location = "$((Get-Location).Drive.Name.ToLower())$Location"

    # Check if in the debugger.
    If (Test-Path -Path Variable:/PSDebugContext) {
        $DebugStart = '[DBG]: '
        $DebugEnd = ']'
    }

    # Actual prompt and title.
    $Host.UI.RawUI.WindowTitle = "$HostName $PSver`: $DebugStart[$UserComputer $Location]$DebugEnd$Symbol"
    "$DebugStart[$UserComputer $Location]$DebugEnd$PSVer$Symbol "
}

 

Linux Prompt on Windows – Part V

http://tommymaynard.com/an-addition-to-the-linux-powershell-prompt-iv-2016/

http://tommymaynard.com/an-addition-to-the-linux-powershell-prompt-ii-2016/

http://tommymaynard.com/an-addition-to-the-linux-powershell-promp-2016/

http://tommymaynard.com/duplicate-the-linux-prompt-2016/

Linux Prompt on Windows – Part IV

Sometime ago I wrote a Linux lookalike prompt. Since then, I’ve continued to modify it as I decided it needed changes. Today, I have a newer version, so I figured I should drop it here, as I have previously.

The difference in this version is that it adds a / between the c (C:\ drive) and ~ when I’m in my “C:\users\tommymaynard” directory, or somewhere further nested in this directory. So yeah, as of today, Monday, September 19, 2016, this is the newest version.

So you can see it before you buy it — it’s actually free — here’s a few examples of what the prompt will look like based on your location within the file system. It updates the ConsoleHost and ISE’s Window Title, too. Bonus.

# C drive: C:\
[tommymaynard@testsrv01 c/]$ 


# WSMan drive: WSMan:\
[tommymaynard@testsrv01 wsman/]$


# WSMan localhost: WSMan:\localhost
[tommymaynard@testsrv01 wsman/localhost]$


# Users folder: C:\Users
[tommymaynard@testsrv01 c/users]$ 


# Profile folder: C:\Users\tommymaynard
[tommymaynard@testsrv01 c/~]$ 


# Desktop folder: C:\Users\tommymaynard\Desktop
[tommymaynard@testsrv01 c/~/Desktop]$ 


# ProgramData folder: C:\ProgramData
[tommymaynard@testsrv01 c/ProgramData]$ 

And, here’s the prompt function.

Function Prompt {
	(Get-PSProvider -PSProvider FileSystem).Home = $env:USERPROFILE

	# Determine if Admin and set Symbol variable.
	If ([bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).Groups -match 'S-1-5-32-544')) {
		$Symbol = '#'
	} Else {
		$Symbol = '$'
	}
	 
	# Write Path to Location Variable as /.../...
	If ($PWD.Path -eq $env:USERPROFILE) {
		$Location = '/~'
	} ElseIf ($PWD.Path -like "*$env:USERPROFILE*") {
		$Location = "/$($PWD.Path -replace ($env:USERPROFILE -replace '\\','\\'),'~' -replace '\\','/')"
	} Else {
		$Location = "$(($PWD.Path -replace '\\','/' -split ':')[-1])"
	}

	# Determine Host for WindowTitle.
	Switch ($Host.Name) {
		'ConsoleHost' {$HostName = 'ConsoleHost'; break}
		'Windows PowerShell ISE Host' {$HostName = 'ISE'; break}
		default {}
	}

	# Create and write Prompt; Write WindowTitle.
	$Prompt = "[$($env:USERNAME.ToLower())@$($env:COMPUTERNAME.ToLower()) $((Get-Location).Drive.Name.ToLower())$Location]$Symbol"
	$Host.UI.RawUI.WindowTitle = "$HostName`: $Prompt"
	
	"$Prompt "
}

Here are the previous posts on this topic:

http://tommymaynard.com/quick-learn-duplicate-the-linux-prompt-2016/
http://tommymaynard.com/quick-learn-an-addition-to-the-linux-powershell-promp-2016/
http://tommymaynard.com/quick-learn-an-addition-to-the-linux-powershell-prompt-ii-2016/

Update: There’s a part V (five) now. This includes an update to indicate when you’re in debug mode.

Windows PowerShell, is PowerShell

In every post I’ve written here, I’ve always made a conscious effort to use the full term “Windows PowerShell,” before I use “PowerShell” later in the post. Well, those times have changed. With the recent news, dropped yesterday (August 18, 2016), PowerShell is open-source and cross-platform. Windows PowerShell is just PowerShell, and it’s available on Linux and Mac OS.

Here’s one of several stories on yesterday’s news: https://blogs.msdn.microsoft.com/powershell/2016/08/18/powershell-on-linux-and-open-source-2. And here, is the story that mentions the name change: https://blogs.msdn.microsoft.com/powershell/2016/08/17/windows-powershell-is-now-powershell-an-open-source-project-with-linux-support-how-did-we-do-it.

I’ve always been pleased by my site’s tagline: “A Windows PowerShell Resource.” Today, I’ve gone ahead and made the change, too, signifying that I’m ready, as well. There’s isn’t a non-Windows post here, but in time, there may be.

Yesterday, and today.

windows-powershell-is-powershell-2016-01

windows-powershell-is-powershell-2016-02

It’s a new era, now. Everything I’ve read, from people I trust in the PowerShell community, says the same thing. The investment we’ve made in PowerShell will be transferable to these other operating systems. We’re better off, than we were just a day ago.

Linux Prompt on Windows – Part III

Maybe, just maybe, there’s someone else using my “Linux” prompt. Just in case there is, I thought to share the most recent additions. Here’s the first two posts in order, if you’re interested in reading those: Quick Learn – Duplicate the Linux Prompt and Quick Learn – An Addition to the Linux PowerShell Prompt.

The changes are extremely minor. It now includes the drive in the WindowTitle. There was never an indication of what drive you were on (C:\, AD:\, WSMan:\, Env:\, etc.). I’ve also wrapped the prompt inside square brackets. I didn’t do this initially because I didn’t want it to interfere with the way the prompt changes when inside an interactive PS Remoting session. I’m over that; it works just fine. Anyway, the code is below for your testing pleasures. Dump it in your profile to keep it around for good.

If you have questions why I’ve done certain things, then you might want to visit the first two posts linked above. Below the prompt code, I’ve included an image, so you can see it for yourself. If you try the prompt, be sure to change your location within the file system into a nested directory or two, so you can see the prompt update accordingly. It’s a thing of beauty; it really is.

Function Prompt {
	(Get-PSProvider -PSProvider FileSystem).Home = $env:USERPROFILE

	# Determine if Admin and set Symbol variable.
	If ([bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).Groups -match 'S-1-5-32-544')) {
		$Symbol = '#'
	} Else {
		$Symbol = '$'
	}
	 
	# Write Path to Location Variable as /.../...
	If ($PWD.Path -eq $env:USERPROFILE) {
		$Location = '~'
	} ElseIf ($PWD.Path -like "*$env:USERPROFILE*") {
		$Location = $PWD.Path -replace ($env:USERPROFILE -replace '\\','\\'),'~' -replace '\\','/'
	} Else {
		$Location = "$(($PWD.Path -replace '\\','/' -split ':')[-1])"
	}

	# Determine Host for WindowTitle.
	Switch ($Host.Name) {
		'ConsoleHost' {$HostName = 'ConsoleHost'; break}
		'Windows PowerShell ISE Host' {$HostName = 'ISE'; break}
		default {}
	}

	# Create and write Prompt; Write WindowTitle.
	$Prompt = "[$($env:USERNAME.ToLower())@$($env:COMPUTERNAME.ToLower()) $Location $Symbol]"
	$Host.UI.RawUI.WindowTitle = "$HostName $Prompt $((Get-Location).Drive):\"
	"$Prompt "
}

an-addition-to-the-linux-powershell-prompt-II-01

Linux Prompt on Windows – Part II

A while ago, I wrote myself a new prompt function and shared it here. Well, I’m here to report that I’m still using it in both the ConsoleHost and the ISE. Here’s an image from the first post that shows what it looks like.

duplicate-the-linux-prompt01

The thing about this prompt function, is that it also modified the WindowTitle to reflect the exact same information — the user, the computer, the location on the current drive, and whether or not you’re admin (# = admin vs. ~ = not admin). I love that too, but there’s turned out to be one little inconvenience. Besides the minutely different icons, I can’t quickly tell if I’m about to open the ISE or ConsoleHost from its taskbar icon. Therefore, I modified the prompt function every so slightly to indicate which host is which. Take a look.

an-addition-to-my-linux-powershell-prompt01

Now I can better determine which host I want — CH for ConsoleHost and ISE for, well, the ISE — before I bring it back to the front. As expected, it only took a minor change. I added a switch statement that evaluated the value in $Host.Name. Based on its value, it populated a variable called $HostName that’s used as a part of the assigned valued in the WindowTitle.

Function Prompt {
	(Get-PSProvider -PSProvider FileSystem).Home = $env:USERPROFILE

	# Determine if Admin and set Symbol variable.
	If ([bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).Groups -match 'S-1-5-32-544')) {
		$Symbol = '#'
	} Else {
		$Symbol = '$'
	}
	 
	# Write Path to Location Variable as /.../...
	If ($PWD.Path -eq $env:USERPROFILE) {
		$Location = '~'
	} ElseIf ($PWD.Path -like "*$env:USERPROFILE*") {
		$Location = $PWD.Path -replace ($env:USERPROFILE -replace '\\','\\'),'~' -replace '\\','/'
	} Else {
		$Location = "$(($PWD.Path -replace '\\','/' -split ':')[-1])"
	}

	# Determine Host for WindowTitle.
	Switch ($Host.Name) {
		'ConsoleHost' {$HostName = 'CH '; break}
		'Windows PowerShell ISE Host' {$HostName = 'ISE'; break}
		default {}
	}

	# Create and write Prompt; Write WindowTitle.
	$Prompt = "$($env:USERNAME.ToLower())@$($env:COMPUTERNAME.ToLower()) $Location $Symbol "
	$Host.UI.RawUI.WindowTitle = "$HostName`: $Prompt"
	$Prompt
}

Update: After a week or so, I updated the function again. I couldn’t stand the capital CH and ISE. So, that’s fixed: It’s ch and ise, now. There may come another change, too. When I’m not on the C:\ drive, I’d like to include an indication in the WindowTitle. Here’s the update.

Linux Prompt on Windows – Part I

I already have an answer to the question, “Why?” Because, I can. At some point in the last few days, I decided I would attempt to replicate the Linux prompt in PowerShell. So I did it, and I thought I would share it. I’ve broken this up a little with the full function toward the bottom of this evening’s post.

In this first section, we’ve created the prompt function’s basic structure and added our first bit of code. This code determines if the user that started the Windows PowerShell session is an administrator or not. If they are, they get the # symbol as part of the prompt, and if they’re not, they get the $ symbol.

Function Prompt {
    If ([bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).Groups -match 'S-1-5-32-544')) {
        $Symbol = '#'
    } Else {
        $Symbol = '$'
    }
}

The next addition includes the logic to determine how to write the path inside the prompt. If the current path is C:\Users\<CurrentUser>, it enters a tilde (~). If the path includes the C:\Users\<CurrentUser> path, in addition to one or more directories, it will enter a tilde and the other directory or directories, such as ~/Desktop, or ~/Favorites/Links. In the last case, it’ll simply list the current path after replacing the backslashes with forward slashes and dumping the drive letter and colon. In all instances, in fact, all (Windows) backslashes, will be replaced with (Unix/Linux) forward slashes.

Function Prompt {
    If ([bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).Groups -match 'S-1-5-32-544')) {
        $Symbol = '#'
    } Else {
        $Symbol = '$'
    }

    If ($PWD.Path -eq $env:USERPROFILE) {
        $Location = '~'
    } ElseIf ($PWD.Path -like "*$env:USERPROFILE*") {
        $Location = $PWD.Path -replace ($env:USERPROFILE -replace '\\','\\'),'~' -replace '\\','/'
    } Else {
        $Location = "$(($PWD.Path -replace '\\','/' -split ':')[-1])"
    }
}

The last section is where the prompt function actually writes the prompt to the screen. It’s the simple combination of the current user, an @ character, the computer name, the path, and the proper symbol (# or $). As you may notice, I’ve written the code to force the case of the current user and computer to lowercase.

Function Prompt {
    If ([bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).Groups -match 'S-1-5-32-544')) {
        $Symbol = '#'
    } Else {
        $Symbol = '$'
    }

    If ($PWD.Path -eq $env:USERPROFILE) {
        $Location = '~'
    } ElseIf ($PWD.Path -like "*$env:USERPROFILE*") {
        $Location = $PWD.Path -replace ($env:USERPROFILE -replace '\\','\\'),'~' -replace '\\','/'
    } Else {
        $Location = "$(($PWD.Path -replace '\\','/' -split ':')[-1])"
    }

    "$($env:USERNAME.ToLower())@$($env:COMPUTERNAME.ToLower()) $Location $Symbol "
}

In closing, I’ve included a gif of the prompt and an example of moving though the directory structure. While I typically only use full cmdlet names in my posts, this example does include aliases for the Set-Location cmdlet (cd, sl, and even chdir). Due to this function being saved in my profile script, this prompt displays immediately when a new console is opened, and every time after that. As someone that’s written a few different prompt functions, this one’s a keeper. I already can’t imaging switching back. On that note, you might not want to test it out.

duplicate-the-linux-prompt01

tommymaynard@srv01 / # $PWD.Path
C:\
tommymaynard@srv01 / # cd C:\Windows\
tommymaynard@srv01 /Windows # cd .\System32\
tommymaynard@srv01 /Windows/System32 # chdir ..
tommymaynard@srv01 /Windows # chdir ..
tommymaynard@srv01 / # sl /users
tommymaynard@srv01 /users # sl /users/tommymaynard2 # Not my current user.
tommymaynard@srv01 /users/tommymaynard2 # cd ..
tommymaynard@srv01 /users # cd C:\Users\tommymaynard\ # My current user.
tommymaynard@srv01 ~ # cd .\Desktop\
tommymaynard@srv01 ~/Desktop # cd ..
tommymaynard@srv01 ~ # cd .\Favorites\Links\
tommymaynard@srv01 ~/Favorites/Links # sl /
tommymaynard@srv01 / # cd /users
tommymaynard@srv01 /users # chdir \
tommymaynard@srv01 / #

Update1: A day later and I still love my new PowerShell prompt. I’ve made a minor change, however. The last line in the function is now the following three lines. It stores the prompt in a variable called $Prompt, modifies the title of the window to the $Prompt value, and then writes the prompt. In the past my window’s title indicate the computer name. Now it indicates that information, as well as the current user, the location on the current drive, and whether or not I’m running the session as an administrator.

...
	$Prompt = "$($env:USERNAME.ToLower())@$($env:COMPUTERNAME.ToLower()) $Location $Symbol "
	$Host.UI.RawUI.WindowTitle = $Prompt
	$Prompt
}

Update2: It occurred to me today that by entering the tilde character, such as Set-Location -Path ~, it moves you to the location stored in the Home property of the FileSystem PSProvider. Because of this, I opted to add another line, just before the beginning of the prompt function. Setting this property to $env:USERPROFILE, allows me to quickly move to C:\Users\<CurrentUser>. I should note that this property is sometimes already set. In those cases, this is just a precaution that the ~ character will move you back home.

(Get-PSProvider -PSProvider FileSystem).Home = $env:USERPROFILE
Function Prompt {
...
}

In case you want to take this prompt function for a spin, and you do, here’s everything. Copy and paste it to your console and hit Enter a couple times and try it out. If you hate it, close and reopen the PowerShell console and it never existed. Cheers.

(Get-PSProvider -PSProvider FileSystem).Home = $env:USERPROFILE
Function Prompt {
    If ([bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).Groups -match 'S-1-5-32-544')) {
        $Symbol = '#'
    } Else {
        $Symbol = '$'
    }
 
    If ($PWD.Path -eq $env:USERPROFILE) {
        $Location = '~'
    } ElseIf ($PWD.Path -like "*$env:USERPROFILE*") {
        $Location = $PWD.Path -replace ($env:USERPROFILE -replace '\\','\\'),'~' -replace '\\','/'
    } Else {
        $Location = "$(($PWD.Path -replace '\\','/' -split ':')[-1])"
    }

	$Prompt = "$($env:USERNAME.ToLower())@$($env:COMPUTERNAME.ToLower()) $Location $Symbol "
	$Host.UI.RawUI.WindowTitle = $Prompt
	$Prompt
}