Tag Archives: Linux

An Addition to the Linux PowerShell Prompt 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.

Quick Learn – An Addition to the Linux PowerShell Prompt II

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

Quick Learn – An Addition to the Linux PowerShell Prompt

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.

Quick Learn – Duplicate the Linux Prompt

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
}